Scala RegEx字符串提取器行为不一致

时间:2016-06-05 04:06:03

标签: java regex string scala pattern-matching

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

一个用于.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文件没有匹配?

1 个答案:

答案 0 :(得分:1)

<强>

  

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

     

\S*\s+//\s{1}([^\.java]+)\.java 表示匹配除了字符类中存在的 字符 之外的任何内容。

在你的第一个正则表达式

\S*
  

\s+匹配任何内容,因为启动时有空格

     

//匹配正在开始的空格

     

//字面匹配\s{1}

     

[^\.java]匹配下一个空格

您使用.表示匹配除 java或{{1}以外的任何内容可以写成[^.jav]

因此,现在要测试的左侧字符串是

Tester.java

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

在你的第二个正则表达式

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

\S*匹配任何内容,因为启动时有空格

     

\s+匹配正在开始的空格

     

//字面匹配//

     

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

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

你现在有

Hello.scala

但是(un)幸运的是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

{1}中不需要\s{1}。您只需将其写为\s,它就会匹配一个空格,如

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