【问题标题】:Scala RegEx String extractors behaving inconsistentlyScala RegEx 字符串提取器行为不一致
【发布时间】:2016-10-04 22:26:07
【问题描述】:

我有两个正则表达式提取器。

一个用于 .java 文件,另一个用于 .scala 文件

val JavaFileRegEx =
  """\S*
     \s+
     //
     \s{1}
     ([^\.java]+)
     \.java
  """.replaceAll("(\\s)", "").r

val ScalaFileRegEx =
  """\S*
     \s+
     //
     \s{1}
     ([^\.scala]+)
     \.scala
  """.replaceAll("(\\s)", "").r

我想使用上面的这些提取器从下面的示例代码中提取一个 java 文件名和一个 scala 文件名。

val string1 = " // Tester.java"
val string2 = " // Hello.scala"

string1 match {
  case JavaFileRegEx(fileName1) => println(" Java file: " + fileName1)
  case other => println(other + "--NO_MATCH")
}
string2 match {
  case ScalaFileRegEx(fileName2) => println(" Scala file: " + fileName2)
  case other => println(other + "--NO_MATCH")
}

我得到这个输出表明 .java 文件匹配但 .scala 文件不匹配。

 Java file: Tester
 // Hello.scala--NO_MATCH

Java文件匹配而.scala文件不匹配是怎么回事?

【问题讨论】:

  • 您在[^\.scala][^\.java] 中对字符类的使用都是错误的
  • @rock321987 - 我对“^”字符感到困惑。我认为[^\.java] 的意思是“匹配所有内容直到 .java”
  • 表示不匹配该集合中的任何字符/\|/.|s|c|a|l|a。 hello 包含一个“l”,因此不匹配。我建议您只使用\w 而不是字符类。如果 '。'可以是文件名的一部分,然后使用[\w.]。正则表达式的其余部分 (/.scala) 仍然需要匹配。您也可以使用 ? 来确定。
  • 例如:\S*\s+//\\s{1}([\w.]+)\.java.
  • Scala 不支持(?x) 修饰符吗?我知道Java可以。将(?x) 作为正则表达式中的第一件事,您不必为.replaceAll("(\\s)", "") 步骤而烦恼。

标签: java regex string scala pattern-matching


【解决方案1】:

注意

[] 表示字符类。它只匹配一个字符。

[^] 表示匹配任何除了字符类中存在的字符

在你的第一个正则表达式中

\S*\s+//\s{1}([^\.java]+)\.java

\S* 不匹配,因为开始时有空格

\s+ 匹配开头的空格

// 匹配 // 字面意思

\s{1} 匹配下一个空格

您正在使用[^\.java],它表示匹配除之外的任何内容.java,可以写成[^.jav]

所以,现在要测试的左边字符串是

Tester.java

(不)幸运的是,Tester 中的任何字符都不匹配 .jav,直到我们遇到 .。所以Tester 匹配,然后java 也匹配。

在你的第二个正则表达式中

\S*\s+//\s{1}([^\.scala]+)\.scala

\S* 不匹配,因为开始时有空格

\s+ 匹配开头的空格

// 匹配 // 字面意思

\s{1} 匹配下一个空格

现在,您正在使用[^\.scala],它表示匹配除之外的任何内容.scala 可以是写成[^.scla]

你现在有

Hello.scala

但幸运的是,Hello 这里包含l,根据字符类,这是不允许的,并且正则表达式失败。

如何纠正?

我只会修改一点你的正则表达式

\S*\s+//\s{1}([^.]*)\.java
              <-->
   This says that match anything except .
   You can also use \w here instead if [^.]

Regex Demo

\S*\s+//\s{1}([^.]*)\.scala

Regex Demo

\s{1} 中不需要{1}。你可以简单地把它写成\s,它会匹配一个空格,比如

\S*\s+//\s([^.]*)\.java

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 2014-06-24
    • 1970-01-01
    • 2019-03-14
    • 2023-01-07
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多