MQTT सदस्यता विषय मैच


10

पृष्ठभूमि

MQTT (संदेश कतारबद्ध टेलीमेट्री ट्रांसपोर्ट) एक आईएसओ मानक प्रकाशित-सदस्यता-आधारित मैसेजिंग प्रोटोकॉल ( विकिपीडिया ) है।

प्रत्येक संदेश में एक विषय होता है, जैसे निम्नलिखित उदाहरण:

  • myhome/groundfloor/livingroom/temperature
  • USA/California/San Francisco/Silicon Valley
  • 5ff4a2ce-e485-40f4-826c-b1a5d81be9b6/status
  • Germany/Bavaria/car/2382340923453/latitude

MQTT क्लाइंट वाइल्डकार्ड का उपयोग करके संदेश विषयों की सदस्यता ले सकते हैं:

  • एकल स्तर: +
  • सभी स्तरों के बाद: #

उदाहरण के लिए, सदस्यता myhome/groundfloor/+/temperatureइन परिणामों ( बोल्ड में गैर-अनुरूपता ) का उत्पादन करेगी :

✅ MyHome / groundfloor / livingroom / तापमान
✅ MyHome / groundfloor / रसोई / तापमान
❌ MyHome / groundfloor / livingroom / चमक
❌ MyHome / firstfloor / livingroom / तापमान
गेराज / groundfloor / फ्रिज / तापमान

जबकि सदस्यता +/groundfloor/#इन परिणामों का उत्पादन करेगी:

✅ MyHome / groundfloor / livingroom / तापमान
✅ MyHome / groundfloor / रसोई / चमक
✅ गेराज / groundfloor / फ्रिज / तापमान / अधिक / विशिष्ट / क्षेत्रों
❌ MyHome / firstfloor / livingroom / तापमान
❌ MyHome / तहखाने / कोने / तापमान

अधिक जानकारी यहाँ

काम

एक समारोह / कार्यक्रम को लागू करें दो तार को स्वीकार करने और एक बूलियन वापस करने के लिए। पहला तार विषय का विषय है, दूसरा मापदंड विषय है। मापदंड विषय उपर्युक्त विस्तृत सदस्यता सिंटैक्स का उपयोग करता है। फ़ंक्शन सत्य है जब विषय मापदंड से मेल खाता है।

इस कार्य के लिए नियम:

  • विषय ASCII हैं
  • #वाइल्डकार्ड से परे कोई मानदंड फ़ील्ड नहीं हैं
  • वाइल्डकार्ड विषय विषयों में दिखाई नहीं देते हैं
  • विषय क्षेत्रों की संख्या> = मापदंड क्षेत्रों की संख्या
  • कोई 0-वर्ण फ़ील्ड नहीं हैं और न ही आगे की स्लैश के लिए अग्रणी या टेलिंग है

परीक्षण के मामलों

मानदंड 1 = "म्योम / ग्राउंडफ्लोर / + / तापमान"
मानदंड 2 = "+ / ग्राउंडफ्लोर / #"

("एबीसी", "एब") => असत्य
("एबीसी", "एबीसी") => सच
("abc / de", "abc") => false
("myhome / groundfloor / Livingroom / तापमान", मानदंड 1) ) => सत्य
("myhome / groundfloor / रसोई / तापमान", मापदंड 1) => true
("myhome / groundfloor / Livingroom / Bright", मापदंड 1) => झूठा
("myhome / firstfloor / लिविंग रूम / तापमान", मापदंड 1) = > झूठा
("गेराज / ग्राउंडफ्लोर / फ्रिज / तापमान", मानदंड 1) => झूठा
("मायहोम / ग्राउंडफ्लोर / लिविंगरूम / तापमान", मानदंड 2) => सच
("मायहोम / ग्राउंडफ्लोर (रसोई / चमक"), मापदंड 2) => सच
( "गेराज / ग्राउंडफ्लोर / फ्रिज / तापमान / अधिक / विशिष्ट / क्षेत्र ", मानदंड 2) => सत्य
(" मिथहोम / फर्स्ट्लोर / लिविंगरूम / तापमान ", मानदंड 2) => असत्य
("myhome / तहखाने / कोने / तापमान", मानदंड 2) => झूठा
("संगीत / केई $ हा / नवीनतम", "+ / केई $ हा / +") => सच


@ हाइपर न्यूट्रिनो, यह एक अच्छा सवाल है। मैं बाड़ पर हूँ। विषय a/b/cमानदंड से मेल नहीं खाता a/b, इसलिए मैं नहीं कहना चाह रहा हूं ।
पैट्रिक

4
क्या /, + और # गारंटी कभी विषय भागों में प्रकट नहीं होती हैं?
जोनाथन एलन

मैं इस लिंक से जुड़े ब्लॉग में देखता हूं कि "इसके अलावा, फॉरवर्ड स्लैश एक वैध विषय है", लेकिन + और # का कोई उल्लेख नहीं है, इसलिए मुझे लगता है कि ये दोनों हो सकते हैं।
जोनाथन एलन

1
@JonathanAllan docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/… से : वाइल्डकार्ड वर्णों का उपयोग Topic फिल्टर में किया जा सकता है, लेकिन एक Topic नाम के अंदर उपयोग नहीं किया जाना चाहिए
Nick Kennedy

2
@NickKennedy - अच्छी खुदाई है, लेकिन हमें वास्तव में इसकी आवश्यकता नहीं है।
जोनाथन एलन

जवाबों:


3

जेली , 20 बाइट्स

ṣ€”/ZṖF”#eƊ¿œiÐḟ”+ZE

एक monadic लिंक पात्रों की सूची की एक सूची को स्वीकार करने, [topic, pattern]है, जो रिटर्न 1या 0मैच या कोई मैच क्रमशः के लिए।

इसे ऑनलाइन आज़माएं! या एक परीक्षण-सूट देखें

कैसे?

ṣ€”/ZṖF”#eƊ¿œiÐḟ”+ZE - Link: list of lists of characters, [topic, pattern]
 €                   - for each:
ṣ                    -   split at occurrences of:
  ”/                 -     '/' character
    Z                - transpose (any excess of topic is kept)
           ¿         - while...
          Ɗ          - ...condition: last three links as a monad:
       ”#            -   '#' character
         e           -   exists in:
      F              -     flatten
     Ṗ               - ...do: pop the tail off
              Ðḟ     - filter discard those for which:
            œi       -   first multi-dimensional index of: ([] if not found, which is falsey)
                ”+   -     '+' character
                  Z  - transpose
                   E - all equal?

2

माणिक , 65 बाइट्स

रेगेक्स समाधान। मैंने Regex.escapeमामले में एक मापदंड नाम जोड़ा है तो ऐसा ही कुछ होता है com.java/string[]/\nया ऐसा कुछ मूर्खतापूर्ण होता है जिसमें रेगेक्स के टुकड़े होते हैं।

->s,c{s=~/^#{Regexp.escape(c).sub('\#','.*').gsub'\+','[^/]*'}$/}

इसे ऑनलाइन आज़माएं!

गैर-रेगेक्स समाधान, 77 बाइट्स

एक अच्छा सरल विभाजन, ज़िप और मैच तकनीक का उपयोग करता है। मुझे पता है कि Regex.escaperegex समाधान के साथ भी कम वैसे भी होता है पहले यह एक विकसित किया है।

->s,c{s.split(?/).zip(c.split ?/).all?{|i,j|i==j||'+#'[j||9]||!j&&c[-1]==?#}}

इसे ऑनलाइन आज़माएं!


.*?के स्थान पर काम करना चाहिए [^/]*
निधि मोनिका का मुकदमा

@NicHartley जो a/+/dविषय के साथ मानदंड के लिए एक गलत मैच को ट्रिगर करेगाa/b/c/d
मान स्याही

आह, तो यह होगा। रैपिंग एक परमाणु समूह में है कि ठीक करता है, लेकिन फिर यह दो बाइट्स लंबा है। ओह अच्छा।
निधि मोनिका का मुकदमा


1

पायथन 3 , 72 बाइट्स

lambda a,b:bool(re.match(b.translate({43:"[^/]+",35:".+"}),a))
import re

इसे ऑनलाइन आज़माएं!

इस समस्या को एक रेगेक्स मैच के लिए तुच्छ रूप से सरल बनाया जा सकता है, हालांकि एक और अधिक दिलचस्प तरीका बेहतर परिणाम दे सकता है।

EDIT I ​​एक 107-बाइट समाधान के साथ आया जिसमें रेगेक्स का उपयोग नहीं किया गया। मुझे नहीं पता कि यह 72 से कम हो सकता है या शायद मैं इस पर सही दृष्टिकोण नहीं देख रहा हूं। हालांकि विभाजित-ज़िप संरचना बहुत बड़ी प्रतीत होती है। यह ऑनलाइन की कोशिश करो!


2
यदि अनुक्रम में कोई अन्य रेगेक्स वर्ण हैं, तो यह विफल हो सकता है। मैं उस के लिए बाहर देखना चाहता हूँ, भले ही वर्तमान परीक्षण मामलों में से कुछ भी दूर से regex की तरह कुछ भी नहीं है।
वैल्यू इंक

... जैसे f('myhome/ground$floor/livingroom/temperature', 'myhome/ground$floor/+/temperature')फेल
जोनाथन एलन

जैसा कि वैल्यू इंक कहता है, +/kei$ha/+मेल नहीं खाता music/kei$ha/latest
चास ब्राउन

1

पायथन 2 , 85 84 80 92 89 बाइट्स

lambda s,c:all(x in('+','#',y)for x,y in zip(c.split('/')+[0]*-c.find('#'),s.split('/')))

इसे ऑनलाइन आज़माएं!

कीड़े को इंगित करने के लिए जोनाथन एलन और वैल्यू इंक का धन्यवाद ।


पर गलत उत्तर देता है f('ab', 'abc')
मूल्य स्याही

@ जोनाथन एलन: दरअसल, नियम कहते हैं कि 'विषय क्षेत्रों की संख्या> = मापदंड क्षेत्रों की संख्या'। लेकिन अन्य समस्याओं को ठीक करने की जरूरत ...
चास ब्राउन

ओह अजीब नियम ने समस्या को संदर्भ दिया!
जोनाथन एलन

1

हास्केल, 76 73 71 67 बाइट्स

(a:b)#(c:d)=a=='+'&&b#snd(span(/='/')d)||a=='#'||a==c&&b#d
a#b=a==b

इसे ऑनलाइन आज़माएं!

संपादित करें: @ बाइट के लिए -4 बाइट्स धन्यवाद।


1
a#b=a==bकुछ बाइट्स के लिए काम करना कम लगता है, जब तक कि मुझे कुछ याद न हो
Cole

@ कोट: हाँ, यह काम करता है। आपका बहुत बहुत धन्यवाद!
नीमी

1

क्लोजर , 107 91 76 65 102 बाइट्स

एक अनाम फ़ंक्शन, विषय nilको सत्य के रूप में और फाल्सी के रूप में लौटाता है (क्लोज़र में मान्य)।

(defn ?[t c](every? #(#{"#""+"(% 0)}(% 1))(apply #(map vector % %2)(map #(re-seq #"[^/]+" %) [t c]))))

107 102 काम कर रहे
91 76 65 सभी रेगेक्स चेरों से हार गए


... और आपके प्रश्न के तहत मेरी टिप्पणी प्रासंगिक हो जाती है
जोनाथन एलन

@JonathanAllan, वास्तव में, सिवाय + और # विषय विषय तार में :) प्रकट नहीं होते हैं
पैट्रिक

मुझे लगता है कि यह विषय music/kei$ha/latestऔर मानदंड +/kei$ha/+(जो एएससीआईआई के लिए वैध और वैध होना चाहिए) के लिए विफल है।
चास ब्राउन

$ के बजाय @ChasBrown, सही, और ^ के साथ; धन्यवाद।
पैट्रिक

1
प्रतिस्थापित करने से पहले पैटर्न के बाद '\ _' और '\ E' के साथ प्रयास करें - स्रोत
जोनाथन एलन


0

अजगर 3, 99 88 बाइट्स

रेगेक्स का उपयोग किए बिना। जोनाथन एलन और चास ब्राउन की कुछ मदद से।

f=lambda s,p:p in(s,'#')or p[:1]in(s[:1],'+')and f(s[1:],p['+'!=p[:1]or(s[:1]in'/')*2:])

f=lambda s,p:s==p or'#'==p[0]or p[0]in(s[0]+'+')and f(s[1:],p['+'!=p[0]or(s[0]=='/')*2:])12 बचाता है। हालांकि, यह कुछ बढ़त के मामलों को संसाधित करने में विफल रहता है जैसे f('abc/ijk/x', 'abc/+/xyz')या f('abc/ijk/xyz', 'abc/+/x'), जो कि के साथ तय किया जा सकता हैf=lambda s,p:s==p or'#'==p[:1]or p[:1]in(s[:1]+'+')and f(s[1:],p['+'!=p[:1]or(s[:1]=='/')*2:])
जोनाथन एलन

यह विफल हो जाता है f('abc','ab')और f('abc/de','abc')(दोनों को वापस लौट जाना चाहिए False, लेकिन इसके बजाय वहाँ है IndexError)।
चास ब्राउन

...or p[:1]in(s[:1],'+')and...किनारे के मामलों को ठीक करता है @ChasBrown और मैंने 2 बाइट की लागत के लिए बताया।
जोनाथन एलन

एक अनुगामी '+' (जैसे f('a/b', 'a/+')) के दूसरे किनारे के मामले को विफल करता है, लेकिन 0 बाइट्स के साथ ठीक करने योग्य है ...or(s[:1]in'/')*2:])
जोनाथन एलन

यह कोशिश करो ऑनलाइन हमेशा सिफारिश की है!
चास ब्राउन

0

चारकोल , 36 बाइट्स

≔⪪S/θ≔⪪S/ηF∧№η#⊟η≔…θLηθF⌕Aη+§≔θι+⁼θη

इसे ऑनलाइन आज़माएं! लिंक कोड के वर्बोज़ संस्करण के लिए है। एक मैच के लिए आउटपुट -(चारकोल के लिए निहित आउटपुट true), बिना मैच के कुछ भी नहीं। स्पष्टीकरण:

≔⪪S/θ

विषय को /एस पर विभाजित करें ।

≔⪪S/η

/एस पर मापदंड विभाजित करें ।

F∧№η#⊟η≔…θLηθ

यदि मानदंड में शामिल हैं (यानी के साथ समाप्त होता है) #तो इसे हटा दें और विषय को मापदंड की नई लंबाई तक ट्रिम करें।

F⌕Aη+§≔θι+

जहां मानदंड हैं +, उस विषय के साथ उस तत्व को बदलें +

⁼θη

मापदंड के साथ विषय की तुलना करें और परिणाम को स्पष्ट रूप से प्रिंट करें।


0

रेटिना 0.8.2 , 42 बाइट्स

%`$
/
+`^([^/]+/)(.*¶)(\1|\+/)
$2
^¶$|¶#/$

इसे ऑनलाइन आज़माएं! स्पष्टीकरण:

%`$
/

/दोनों पंक्तियों के लिए प्रत्यय ।

+`^([^/]+/)(.*¶)(\1|\+/)
$2

बार-बार विषय और मापदंड दोनों के पहले तत्व को हटा दें जबकि वे समान या मानदंड तत्व एक (खुश) है +

^¶$|¶#/$

मानदंड मेल खाता है यदि यह सिर्फ एक है #( /जो पहले जोड़ा गया था) अन्यथा इस बिंदु से विषय और मानदंड दोनों खाली होना चाहिए।




0

जावास्क्रिप्ट, 69 66 बाइट्स

t=>s=>new RegExp(s.split`+`.join`[^/]+`.split`#`.join`.+`).test(t)

इसे ऑनलाइन आज़माएं!


यह विषय music/kei$ha/latestऔर मानदंड +/kei$ha/+(जो एएससीआईआई से वैध होना चाहिए और वैध होना चाहिए) के लिए विफल रहता है ।
चास ब्राउन


0

05AB1E , 21 बाइट्स

ε'/¡}ζʒ'+å≠}˜'#¡н2ôøË

आदेश में एक सूची के रूप में इनपुट [criteria, topic]

इसे ऑनलाइन आज़माएं या सभी परीक्षण मामलों को सत्यापित करें

स्पष्टीकरण:

ε                      # Map both strings in the implicit input-list to:
 '/¡                  '#  Split the string on "/"
                       #   i.e. ["+/+/A/B/#","z/y/A/B/x/w/v/u"]
                       #    → [["+","+","A","B","#"],["z","y","A","B","x","w","v","u"]]
                     # After the map: zip/transpose the two string-lists,
                       # with space as (default) filler
                       #  → [["+","z"],["+","y"],["A","A"],["B","B"],["#","x"],[" ","w"],
                       #     [" ","v"],[" ","u"]]
      ʒ    }           # Filter each pair by:
       '+å≠           '#  Only keep those which do NOT contain a "+"
                       #   → [["A","A"],["B","B"],["#","x"],[" ","w"],[" ","v"],[" ","u"]]
            ˜          # Flatten the filtered list
                       #  → ["A","A","B","B","#","x"," ","w"," ","v"," ","u"]
             '#¡      '# Split the list by "#"
                       #  → [["A","A","B","B"],["x"," ","w"," ","v"," ","u"]]
                н      # Only keep the first part
                       #  → ["A","A","B","B"]
                 2ô    # Split this back into pairs of two
                       #  → [["A","A"],["B","B"]]
                   ø   # Zip/transpose them back
                       #  → [["A","B"],["A","B"]]
                    Ë  # And check if both inner lists are equal
                       #  → 1 (truthy)
                       # (after which the result is output implicitly)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.