【问题标题】:Match several occurrences or zero (in this order) using regular expressions使用正则表达式匹配多个匹配项或零(按此顺序)
【发布时间】:2011-04-26 23:28:30
【问题描述】:

我想使用 Groovy 正则表达式匹配罗马数字(我没有在 Java 中尝试过,但应该是一样的)。 我在这个网站上找到了一个答案,其中有人建议使用以下正则表达式:

/M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})/

问题是像/V?I{0,3}/ 这样的表达式在Groovy 中并不贪心。 因此,对于像“Book number VII”这样的字符串,匹配器 /V?I{0,3}/ 返回“V”而不是“VII”,因为它是期望的。

显然,如果我们使用模式/VI+/,那么我们确实会得到匹配“VII”...但是如果字符串类似于“Book number V”,则此解决方案无效,因为我们将找不到匹配...

我试图通过使用贪婪量词 /VI{0,3}+/ 甚至 /VI*+/ 来强制捕获最大字符,但我仍然得到匹配“V”而不是“VII”

有什么想法吗?

【问题讨论】:

  • 这在 Java 中肯定是贪婪的(在第 3 组中运行“VIII”会得到“VIII”,而不是“V”。同样测试正则表达式 "V?I{0,3}" 也会得到贪婪的结果)。你确定你在 Groovy 中观察到这种行为吗? Groovy 使用不同的正则表达式引擎似乎有点令人惊讶。
  • 嗯?那么,? 贪婪的,但 {n,m} 不是?
  • 也许不是完全在主题上,但正则表达式似乎被过度指定了。它将传递无效的罗马数字,因此不能用于错误检查。然而,它显然是一个 PITA。像[MCDXLIV]+ 这样的东西怎么样?
  • 我只是在 Java 中运行它,结果是正确的。所以Java返回贪婪的结果。但 Groovy 没有。我正在使用 Groovy 控制台为 groovy 1.7.0 运行脚本,并且 {0,3} 并不贪婪。奇怪的是 {n,m} 是贪婪的,但仅当 n!=0 时。同样 .* 仅当匹配 0 个字符不符合模式时才会贪婪。

标签: java regex groovy match roman-numerals


【解决方案1】:

为什么不只是 (IX|IV|V?I{1,3}|V) ?

【讨论】:

  • 谢谢。这很有效,因为 V?I{1,3} 比 V 获得更高的优先级。我只是很困惑,因为 V?I{0,3} 本身应该可以正常工作(它在 Java 中可以,但在 Groovy 中不行)
  • 那么.. 选择这个答案作为“那个”怎么样?
【解决方案2】:

我发现我的错误是什么。 问题是 /V?I{0,3}//V?I*/ 之类的模式即使是 EMPTY 字符串也会遇到......所以对于像 "Book VII" 这样的字符串,匹配器将抛出以下结果匹配:

Result[0] --> ''
Result[1] --> '' 
Result[2] --> ''
Result[3] --> '' 
Result[4] --> '' 
Result[5] --> 'VII'
Result[6] --> '' 

贪婪的结果在那里(Result[5])好吧。 我的问题是我总是选择第一个匹配项(Result[0]),并且仅当空字符串不满足该模式时才有效。

例如,建议的模式/V?I{1,3}|V/ 只会抛出一个结果,所以选择第一个结果匹配就可以了:

Result[0] --> 'VII'

...之所以如此,是因为空字符串不满足该模式。

希望这对其他人有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2014-01-07
    • 2012-06-17
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多