सवाल यह जांचने के लिए कि क्या स्ट्रिंग पूरी तरह से स्कैला में रेगेक्स से मेल खाती है?


मान लें कि मेरे पास रेगेक्स पैटर्न है जो मैं कई स्ट्रिंग्स से मेल खाना चाहता हूं।

val Digit = """\d""".r

मैं सिर्फ यह जांचना चाहता हूं कि दिया गया स्ट्रिंग पूरी तरह से रेगेक्स से मेल खाता है या नहीं। स्कैला में ऐसा करने के लिए एक अच्छा और बेवकूफ तरीका क्या है?

मुझे पता है कि मैं रेगेक्स पर पैटर्न मिलान कर सकता हूं, लेकिन यह इस मामले में वाक्य रचनात्मक रूप से बहुत ही सुखद नहीं है, क्योंकि मेरे पास निकालने के लिए कोई समूह नहीं है:

scala> "5" match { case Digit() => true case _ => false }
res4: Boolean = true

या मैं अंतर्निहित जावा पैटर्न पर वापस आ सकता है:

scala> Digit.pattern.matcher("5").matches
res6: Boolean = true

जो सुरुचिपूर्ण नहीं है, या तो।

क्या कोई बेहतर समाधान है?


68
2018-06-11 09:54


मूल


मुझे लगता है "5" match { case Digit() => true case _ => false } अंतर्निहित पैटर्न ऑब्जेक्ट का उपयोग करने से बेहतर दिखता है। - Mygod


जवाब:


अपने स्वयं के प्रश्न का उत्तर देते हुए मैं "लाइब्रेरी लाइब्रेरी पैटर्न" का उपयोग करूंगा

object RegexUtils {
  implicit class RichRegex(val underlying: Regex) extends AnyVal {
    def matches(s: String) = underlying.pattern.matcher(s).matches
  }
}

और इस तरह इसका इस्तेमाल करें

import RegexUtils._
val Digit = """\d""".r
if (Digit matches "5") println("match")
else println("no match")

जब तक कोई बेहतर (मानक) समाधान के साथ आता है।

टिप्पणियाँ

  • मैं पिंप नहीं था String संभावित साइड इफेक्ट्स के दायरे को सीमित करने के लिए।

  • unapplySeq उस संदर्भ में बहुत अच्छी तरह से पढ़ा नहीं है।


51
2018-06-11 13:59



क्या आपके मन में कोई विशेष साइड इफेक्ट है? मैंने पंप किया String इसके बजाए, और यह अभी तक ठीक काम करता है, इसके बावजूद Stringसदस्य का कार्य matches(regex: String)। - KajMagnus
मैं एक समारोह के साथ pimped misses भी। मैच और मिसमैच :-) लिखना बहुत परेशान है !s.matches(r) के बजाय s misses r। हम्म - KajMagnus
बिल्ट-इन के बारे में कैसे "5" matches "\\d" जो @polygenelubricants सुझाव दिया? - Erik Allik
डेटा एक पैटर्न से मेल खाता है, विपरीत नहीं। रेगेक्स पर स्केलैड "मैचों" के लिए बूलियन की कमी के बारे में एक बड़ा सौदा करता है। निजी तौर पर, मुझे लगता है कि अगर आपने एक क्लंकियर के लिए एक अच्छा मैच बदल दिया है। यदि आप समूहों की परवाह नहीं करते हैं, तो उपयोग करें case r(_*) =>। - som-snytt
बाहरी पुस्तकालय आयात किए बिना ऐसा करने का एक तरीका होना चाहिए ... - Jameela Huq


मैं स्कैला को इतना अच्छी तरह से नहीं जानता, लेकिन ऐसा लगता है कि आप बस ऐसा कर सकते हैं:

"5".matches("\\d")

संदर्भ


48
2018-06-11 10:46



खैर, यह काम करता है, लेकिन यह नुकसान है कि पैटर्न को मिलान करने के हर प्रयास पर संकलित किया गया है। मैं प्रदर्शन कारणों से बचाना चाहता हूं। - mkneissl
@mkneissl: तो यह आपके जैसा दिखता है .pattern.matcher(text).matches जाने का रास्ता है। यदि आप स्कैला का समर्थन करते हैं तो आप कुछ उपयोगिता विधि या ओवरलोडेड ऑपरेटर या कुछ के तहत वर्बोजिटी छुपा सकते हैं। - polygenelubricants
धन्यवाद, यही वह है जो मैं करने जा रहा हूं, मेरा जवाब देखें। मुझे उम्मीद है कि किसी के अपने प्रश्नों का उत्तर देना स्टैक ओवरफ़्लो पर व्यवहार स्वीकार किया जाता है ... मेटा का कहना है कि यह है ... - mkneissl
इस उत्तर के विस्तार के रूप में: वैल regex = "\\ d" .r; "5" .मैच (regex.pattern.pattern) // बूलेन = सच - ed.
@ईडी। यह भी धीमा और क्रूर है, तो क्यों? - Erik Allik


पूरे मैच के लिए आप उपयोग कर सकते हैं unapplySeq। यह विधि लक्ष्य (पूरे मैच) से मेल खाने का प्रयास करती है और मैचों को वापस लाती है।

scala> val Digit = """\d""".r
Digit: scala.util.matching.Regex = \d

scala> Digit unapplySeq "1"
res9: Option[List[String]] = Some(List())

scala> Digit unapplySeq "123"
res10: Option[List[String]] = None

scala> Digit unapplySeq "string"
res11: Option[List[String]] = None

13
2018-06-11 11:58



जबकि सच है, अनुपयोगी और अनुपयोगी का प्राथमिक उपयोग निश्चित रूप से है caseए के एस match ब्लॉक। - Randall Schulz


  """\d""".r.unapplySeq("5").isDefined            //> res1: Boolean = true
  """\d""".r.unapplySeq("a").isDefined            //> res2: Boolean = false

10
2017-12-18 06:49



हम्म। एक डुप्लिकेट पोस्ट क्यों करें stackoverflow.com/a/3022478/158823 दो साल बाद? - mkneissl
आपके मूल प्रश्न ने 'सत्य' या 'झूठी' में समाप्त होने वाले परिणाम के लिए पूछा, 'कुछ' या 'कोई नहीं'। जहां तक ​​मुझे पता है कि परिभाषित 2 साल पहले लाइब्रेरी का हिस्सा नहीं था, लेकिन शायद यह था। वैसे भी, मेरा जवाब डुप्लिकेट नहीं है ;-) - Jack
मैं देखता हूं, यह एक डुप्लिकेट नहीं है। माफ़ कीजिये। - mkneissl
कोई जांच नहीं ;-) मेरी गलती, मुझे समझाया जाना चाहिए कि मैं क्यों उपयोग कर रहा हूं मेरे जवाब में परिभाषित है। सिर्फ एक जवाब के रूप में कोड देना आम तौर पर एक बुरा विचार है, इसलिए यह मेरा बुरा है। - Jack


जवाब रेगेक्स में है:

val Digit = """^\d$""".r

फिर मौजूदा तरीकों में से एक का उपयोग करें।


3
2018-06-12 17:13



मुझे नहीं लगता कि एंकर यहां मुद्दा है। String/Pattern/Matcher.matches, जावा में कम से कम, पहले स्ट्रिंग मैच पहले से ही है। मुझे लगता है कि यह मुद्दा स्कैला में regex-ing के लिए शैली / मुहावरे है, यानी वे "मौजूदा तरीकों में से एक" क्या हैं। - polygenelubricants
@polygenelubricants खैर, Matcher.matches एक विचलन है। ठीक है, यह कुछ अनुकूलन संभव बनाता है, हालांकि मुझे नहीं पता कि जावा लाइब्रेरी वास्तव में इसका लाभ उठाती है या नहीं। लेकिन वो मानक नियमित अभिव्यक्तियों के लिए रास्ता व्यक्त करना कि एक पूर्ण मिलान की आवश्यकता है एंकरों का उपयोग करना। चूंकि स्कैला लाइब्रेरी करता है नहीं एक पूर्ण मिलान विधि प्रदान करें, फिर इसे करने का उचित तरीका एंकर का उपयोग करना है। या तो, या जावा पुस्तकालय का उपयोग करें। - Daniel C. Sobral
एंकरिंग समस्या नहीं है। वासील के जवाब में "123" उदाहरण भी देखें। - mkneissl
@ डैनियल आप शायद इस बिंदु को याद कर रहे हों - मेरा सवाल था, अगर मुझे केवल यह जानने की ज़रूरत है कि रेगेक्स पूरी तरह से मेल खाता है, तो स्कैला में इसे व्यक्त करने का एक अच्छा तरीका क्या है। बहुत सारे कामकाजी समाधान हैं, लेकिन संक्षेप में मुझे लगता है कि रेगेक्स में एक विधि गायब है जो बस ऐसा करती है और कुछ भी नहीं। अपने कमेंट में प्रश्न का उत्तर देने के लिए: unapplySeq से अंतर खोजने के लिए FirstMatch है, कि मुझे एंकर जोड़ने के लिए Regex को बदलना है। दोनों विधियां न तो तुरंत मेरे इरादे को व्यक्त करती हैं और न ही एक बुलियन मूल्य लौटाती हैं, मुझे विकल्प से बूलियन तक जाना होगा (कोई समस्या नहीं है, लेकिन अधिक अव्यवस्था जोड़ना)। - mkneissl
@mkneissl मैं जावा की अवधारणा को नापसंद करता हूं matches, लेकिन ठीक है। से संबंधित Option बनाम Boolean, जोड़ें nonEmpty अंत तक और आप पाएंगे Boolean। - Daniel C. Sobral


मानक स्कैला लाइब्रेरी का उपयोग करना और एक पूर्व संकलित रेगेक्स पैटर्न और पैटर्न मिलान (जो कला की स्कैला अवस्था है):

val digit = """(\d)""".r

"2" match {
  case digit( a) => println(a + " is Digit")
  case _ => println("it is something else")
}

पढ़ने के लिए और अधिक: http://www.scala-lang.org/api/2.12.1/scala/util/matching/index.html


-1
2017-08-24 08:52