使用正则表达式匹配以特定字符串开头的所有行

3
我有一个非常长的cfg文件,我需要找到以特定字符串开头的行的最新出现。以下是cfg文件的示例:
...
# format: - search.index.[number] = [search field]:element.qualifier
...    
search.index.1 = author:dc.contributor.*
...
search.index.12 = language:dc.language.iso
...
jspui.search.index.display.1 = ANY
...

我需要能够获取以search.index.[number]开头的行的最后一次出现,更具体地说:我需要那个数字。对于上面的片段,该数字将是12
正如您所看到的,还有其他包含该模式的行,但我不想匹配那些行。
我正在使用Groovy作为编程/脚本语言。
感谢任何帮助!

我敢打赌会有类似于“lastIndexOf()”的东西。 - Javier Diaz
3个回答

1

尝试将此作为您的表达式:

^search\.index\.(\d+)/

然后使用Groovy,您可以通过以下方式获取结果:

 matcher[0][0]

这里是一个解释页面。


这不会匹配任何内容,因为它没有启用多行模式。即使它匹配成功了(如果search.index.1 = author:dc.contributor.*在第一行),它也只会返回“search.index.1”,而不是被组所搜索的数字。 - tim_yates
由于某些原因,指向groovy.codehaus.org的链接已经失效。更新的链接http://docs.groovy-lang.org/latest/html/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html似乎表明一堆正则表达式被“弃用”...仍在寻找最终答案。 - MarkHu

1
我不认为你应该去尝试,但是......
如果你可以进行多行搜索(无论如何,在这里你必须这样做),唯一的方法就是倒着读取文件。因此首先使用.*(嗯嗯嗯)吃掉所有内容(如果你可以使点匹配所有内容,则为(?:.|\s)*,如果不能则为.*)。现在匹配你的模式search\.index\.(\d+)。并且你想在行的开头匹配这个模式:(?:^|\n)(希望你没有使用某些不使用\n作为换行符的疯狂格式)。

所以......

(?:.|\s)*(?:^|\n)search\.index\.(\d+)

数字应该在第一个匹配组中。( JavaScript中的测试 )
PS:我不懂groovy,如果完全不合适,请见谅。
编辑: 这也应该可以工作:
search\.index\.(\d+)(?!(?:.|\s)*?(?:^|\n)search\.index\.\d+)

非常感谢您的快速回复!我正在尝试稍微修改过的正则表达式,看起来像是 (?:^|\n)search\.index\.(\d+)(因为完整版本会导致 StackOverflowError)。看起来它能够工作!只需要根据我的需求进行一些调整。非常感谢您的答案和解释! - Pieter VDE
@Dreamonic,那只是提供信息而已。我觉得有趣的是你可以通过“黑客攻击”系统来只用一个正则表达式实现它 ;) - Loamhoof

1
你尝试过吗:

def m = lines =~ /(?m)^search\.index\.(\d+)/
m[ -1 ][ 1 ]

1
(?m) 告诉 Groovy 进行多行正则表达式匹配,然后 m[-1] 告诉它获取最后一次匹配,而 [ 1 ] 则从该最后一次匹配中获取第一个组。因此,在您的示例中,m[0][1] 是第一次匹配的 1,而 m[-1][1] 将是最后一次匹配的 12 - tim_yates
突然,当我再次运行这段代码时,出现以下错误:索引超出范围 0..-1 (索引 = -1) 有任何想法为什么会出现这种情况? - Pieter VDE
@Dreamonic,它没有找到匹配项。因此,“search.index.”在文本中不存在。 - tim_yates
奇怪的是,我没有改变文件。search.index.仍然存在!文件引用也是正确的,一切都和它工作时一样... - Pieter VDE
@Dreamonic,一定有些变化了...不然的话,它还能正常工作的 ;-) - tim_yates
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接