【问题标题】:Scala Escape Character RegexScala转义字符正则表达式
【发布时间】:2016-11-30 05:11:00
【问题描述】:

如何编写表达式来过滤输入,使其格式为 (AAA) 其中 A 是从 0 到 9 的数字。 例如:(123)、(592)、(999)

【问题讨论】:

  • 反向引用(\d)\1*

标签: regex scala escaping character


【解决方案1】:

通常你想做的不仅仅是过滤。

scala> val r = raw"\(\d{3}\)".r
r: scala.util.matching.Regex = \(\d{3}\)

scala> List("(123)", "xyz", "(456)").filter { case r() => true case _ => false }
res0: List[String] = List((123), (456))

scala> import PartialFunction.{cond => when}
import PartialFunction.{cond=>when}

scala> List("(123)", "xyz", "(456)").filter(when(_) { case r() => true })
res1: List[String] = List((123), (456))

保留每个输入的所有匹配项:

scala> List("a(123)b", "xyz", "c(456)d").flatMap(s =>
     | r.findAllMatchIn(s).map(_.matched).toList)
res2: List[String] = List((123), (456))

scala> List("a(123)b", "xyz", "c(456)d(789)e").flatMap(s =>
     | r.findAllMatchIn(s).map(_.matched).toList)
res3: List[String] = List((123), (456), (789))

只保留第一个:

scala> val r = raw"(\(\d{3}\))".r.unanchored
r: scala.util.matching.UnanchoredRegex = (\(\d{3}\))

scala> List("a(123)b", "xyz", "c(456)d(789)e").flatMap(r.unapplySeq(_: String)).flatten
res4: List[String] = List((123), (456))

scala> List("a(123)b", "xyz", "c(456)d(789)e").collect { case r(x) => x }
res5: List[String] = List((123), (456))

保持匹配的整行:

scala> List("a(123)b", "xyz", "c(456)d(789)e").collect { case s @ r(_*) => s }
res6: List[String] = List(a(123)b, c(456)d(789)e)

Java API:

scala> import java.util.regex._
import java.util.regex._

scala> val p = Pattern.compile(raw"(\(\d{3}\))")
p: java.util.regex.Pattern = (\(\d{3}\))

scala> val q = p.asPredicate
q: java.util.function.Predicate[String] = java.util.regex.Pattern$$Lambda$1107/824691524@3234474

scala> List("(123)", "xyz", "(456)").filter(q.test)
res0: List[String] = List((123), (456))

【讨论】:

    【解决方案2】:

    通常您使用字符串上可用的.r 方法创建正则表达式,例如"[0-9]".r。但是,正如您所注意到的,这意味着您不能插入转义字符,因为解析器认为您想要将转义字符插入字符串,而不是正则表达式。

    为此,您可以使用 Scala 的三引号字符串,它可以创建精确字符序列的字符串,包括反斜杠和换行符。 要创建一个像你描述的正则表达式,你可以写"""\(\d\d\d\)""".r。以下是它的使用示例:

    val regex = """\(\d\d\d\)""".r.pattern
    Seq("(123)", "(---)", "456").filter(str => regex.matcher(str).matches)
    

    【讨论】:

    • List("(123)", "xyz", "(456)").filter(pattern.asPredicate.test) 或类似的。
    猜你喜欢
    • 1970-01-01
    • 2020-02-05
    • 2010-12-22
    • 2010-09-21
    • 2020-07-24
    相关资源
    最近更新 更多