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


80

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

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

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

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

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

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

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

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

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


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

जवाबों:


66

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

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 उस संदर्भ में बहुत अच्छी तरह से नहीं पढ़ता है।


क्या आपके मन में कोई विशेष दुष्प्रभाव था? मैंने Stringइसके बजाय, और यह अब तक ठीक काम करता है, Stringसदस्य के कार्य के बावजूद ठीक है matches(regex: String)
काजागमनस

1
मैं एक फंक्शन के साथ missesभी बहुत खुश थी। मैच और मिसमैच :-) इसके !s.matches(r)बजाय लिखना कितना कष्टप्रद है s misses r। हम्म
काजगमैनस

1
कैसे के बारे में बनाया "5" matches "\\d"@ जो में @ ऑक्सीजनील स्नेहक का सुझाव दिया?
एरिक कपलुन

2
डेटा एक पैटर्न से मेल खाता है, न कि इसके विपरीत। रेगेक्स पर स्केलडॉक "मैचों" के लिए बूलियन की कमी के बारे में एक बड़ी बात करता है। व्यक्तिगत रूप से, मुझे लगता है कि आपने किसी और के लिए एक अच्छे मैच की अदला-बदली की है। यदि आप समूहों की परवाह नहीं करते हैं, तो उपयोग करें case r(_*) =>
सोम-संवत

बाहरी पुस्तकालय को आयात किए बिना ऐसा करने का एक तरीका होना चाहिए ...
जमीला हक

56

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

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

संदर्भ


25
ठीक है, यह काम करता है, लेकिन इसका नुकसान यह है कि पैटर्न मिलान करने की हर कोशिश पर संकलित है। मैं प्रदर्शन कारणों से बचना चाहूंगा।
mkneissl

3
@mkneissl: तब ऐसा लगता है कि आपका .pattern.matcher(text).matchesरास्ता तय करना है। आप कुछ उपयोगिता विधि या अतिभारित ऑपरेटर के तहत वर्बोसिटी को छुपा सकते हैं या यदि स्केला इसका समर्थन करता है तो कुछ।
पॉलीजेन लुब्रिकेंट्स

4
धन्यवाद, यही मैं करने जा रहा हूं, मेरा उत्तर देखें। मुझे उम्मीद है कि स्टैक ओवरफ्लो पर किसी के खुद के सवालों के जवाब को स्वीकार किया जाता है ... मेटा कहता है ...
mkneissl

2
@ईडी। यह भी धीमी और cruftier है, तो क्यों?
एरिक कप्लून

संदर्भ के रूप में दिया गया लिंक टूटा हुआ है
Valy Dia

13

पूर्ण मैच के लिए आप अनपेस्इक का उपयोग कर सकते हैं । यह विधि लक्ष्य (पूरे मैच) का मिलान करने की कोशिश करती है और मैच लौटाती है।

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

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

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

हम्म। दो साल बाद stackoverflow.com/a/3022478/158823 की डुप्लिकेट पोस्टिंग क्यों ?
mkneissl

2
आपके मूल प्रश्न का परिणाम 'सत्य' या 'असत्य' में समाप्त होता है, न कि 'कुछ' या 'कोई नहीं'। जहां तक ​​मुझे पता है कि डिफाइंड 2 साल पहले लाइब्रेरी का हिस्सा नहीं था, लेकिन शायद यह था। वैसे भी, मेरा जवाब डुप्लिकेट नहीं है ;-)
जैक

मैं देखता हूं, यह कोई नकल नहीं है। माफ़ करना।
mkneissl

1
कोई प्रोब्स ;-) मेरी गलती, मुझे समझाया जाना चाहिए कि मैं अपने जवाब में isDefined का उपयोग क्यों कर रहा हूं। बस एक उत्तर के रूप में कोड देना आमतौर पर एक बुरा विचार है, इसलिए यह मेरा बुरा है।
जैक

1

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

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

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


3
मुझे नहीं लगता कि एंकर यहां मुद्दा है। String/Pattern/Matcher.matches, जावा में कम से कम, पूरे स्ट्रिंग मैच पहले से ही है। मुझे लगता है कि इस मुद्दे को स्कैला में रेगेक्स-इंग के लिए सिर्फ शैली / मुहावरा है, अर्थात "मौजूदा तरीकों में से एक" क्या हैं।
पॉलीजेन लुब्रीकेंट

@ पॉलीऑक्सिहाइडेलेबुलेंट अच्छी तरह से, Matcher.matchesएक वशीकरण है। ठीक है, यह कुछ अनुकूलन संभव बनाता है, हालांकि मुझे नहीं पता कि जावा पुस्तकालय वास्तव में इसका लाभ उठाता है या नहीं। लेकिन रेगुलर एक्सप्रेशंस के लिए मानक तरीका है कि एंकर का उपयोग करने के लिए एक पूर्ण मैच की आवश्यकता है। चूंकि स्काला लाइब्रेरी पूर्ण मिलान विधि प्रदान नहीं करती है, इसलिए ऐसा करने का उचित तरीका एंकरों का उपयोग करना है। या तो, या जावा पुस्तकालय का उपयोग करें।
डैनियल सी। सोबरल

एंकरिंग समस्या नहीं है। वासिल के उत्तर में "123" उदाहरण भी देखें।
mkneissl

5
@ डैनियल आप इस बिंदु को याद कर रहे होंगे - मेरा सवाल था, अगर मुझे केवल यह जानना है कि क्या एक रेगेक्स पूरी तरह से मेल खाता है, तो स्काला में इसे व्यक्त करने का एक अच्छा तरीका क्या है। बहुत सारे काम करने वाले समाधान हैं, लेकिन सारांश में मुझे लगता है कि रेगेक्स में एक विधि गायब है जो बस ऐसा करती है और कुछ नहीं। आपकी प्रशंसा में प्रश्न का उत्तर देने के लिए: unapplySeq से findFirstMatch में अंतर यह है कि मुझे एंकर को जोड़ने के लिए Regex को बदलना होगा। दोनों विधियां न तो तुरंत मेरा इरादा व्यक्त करती हैं और न ही एक बूलियन मान लौटाती हैं, यही कि मुझे ऑप्शन से बुलियन (कोई समस्या नहीं है, लेकिन अधिक अव्यवस्था जोड़कर) जाना होगा।
mkneissl

1
@mkneissl मैं जावा की अवधारणा को नापसंद करता हूं matches, लेकिन ठीक है। के रूप में Optionबनाम Boolean, जोड़ने के nonEmptyअंत करने के लिए और आप मिल जाएगा Boolean
डैनियल सी। सोबरल

0

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

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/ind.net.html

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.