2011-11-28 1 views
28

正規表現と文字列の一致が頻繁に起こります。 Javaでは:Scalaの正規表現との照合

java.util.regex.Pattern.compile( "\ wの+")マッチャ( "this_is")

痛いと一致します。。。 Scalaには多くの選択肢があります。

  1. "\\w+".r.pattern.matcher("this_is").matches
  2. "this_is".matches("\\w+")
  3. "\\w+".r unapplySeq "this_is" isDefined
  4. val R = "\\w+".r; "this_is" match { case R() => true; case _ => false}

最初は、Javaコードと同じくらい重い重量です。

2番目の問題は、コンパイル済みのパターン("this_is".matches("\\w+".r"))を指定できないことです。 (正規表現を取るメソッドがあるたびに正規表現をとるオーバーロードがあるので、これはアンチパターンと思われます)。

第3の問題は、それが乱用unapplySeqであり、ひどいことです。

正規表現の一部を分解するときに4番目の値は大きいですが、ブール値の結果のみを必要とする場合は重すぎることになります。

正規表現との一致を確認する簡単な方法がありませんか? String#matches(regex: Regex): Booleanが定義されていない理由はありますか?実際、String#matches(uncompiled: String): Booleanはどこに定義されていますか?それが一致するか、他None場合

scala> val Email = """(\w+)@([\w\.]+)""".r 

findFirstInSome[String]を返します。

+3

'String#matches(string:String)'は、2.9仕様または[StringLike](http://www.scala-lang.org/api/current/index.html)で定義されていないことに注意してください。 #scala.collection.immutable.StringLike)型を標準ライブラリから削除します。実際、Javaの[Strings]の定義のアーティファクトです(http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#matches(java.lang))。文字列))。 – ig0774

+0

最初の例で重すぎるとはどういう意味ですか?コードが長すぎるか、あまりにも多くの作業をしているという意味ですか? –

+1

あまりにも多くのコード、仕事は私が欲しいものです – schmmd

答えて

31

あなたは、このようなパターンを定義することができます。

scala> Email.findFirstIn("[email protected]") 
res1: Option[String] = Some([email protected]) 

scala> Email.findFirstIn("test") 
rest2: Option[String] = None 

あなたも抽出できます。

scala> val Email(name, domain) = "[email protected]" 
name: String = test 
domain: String = example.com 

最後に、あなたはまた、従来のString.matches方法を使用することができます(さらに以前Email Regexpを定義したリサイクル:これは役立つ

scala> "[email protected]".matches(Email.toString) 
res6: Boolean = true 

ホープを

+0

ええ、 "" ^(\ w +)$ "" "findFirstIn(" test_string ")' ... – schmmd

+1

@schmmd 'Regex'を構築する' .r'は忘れないでください。 – David

+0

おっと! 'Regex'で' matches'を定義するのは良いことではないでしょうか? – schmmd

12

私は少し「Pimp My Library」パターンを作成しましたその問題のために。多分それがあなたを助けるでしょう。

import util.matching.Regex 

object RegexUtils { 
    class RichRegex(self: Regex) { 
    def =~(s: String) = self.pattern.matcher(s).matches 
    } 
    implicit def regexToRichRegex(r: Regex) = new RichRegex(r) 
} 

使用例

scala> import RegexUtils._ 
scala> """\w+""".r =~ "foo" 
res12: Boolean = true 
+1

クール! '= 'で終わる演算子は、C++やPythonの規約からのインプレース変異を私に見せてくれるので、私は'〜 'ではなく'〜 '演算子を呼び出します。 –

+0

ええ、私はperl's =〜を目指していましたが、明らかに名前を後方に持っていました。 –

+0

ちょうど私が言及したいと思っていたハスケルは=正規表現を一致させるための演算子もあります。私は '〜='のようにnot-equalsを意味するのに '〜='が使われているのを見ました。 – eriksensei

3

を参照してください。私は通常

val regex = "...".r 
if (regex.findFirstIn(text).isDefined) ... 

を使用するが、私はそれはかなり厄介だと思います。