【问题标题】:RegEx that matching an expression NOT at the beginning of a line匹配不在行首的表达式的正则表达式
【发布时间】:2013-07-06 02:07:36
【问题描述】:

一个多小时以来,我一直在苦苦思索一个表情,但没有结果。所以是时候寻求帮助了。

在以下(多行)文本中:
华尔兹15
华尔兹卷。 15
华尔兹卷。 一个
华尔兹,卷15
15:华尔兹

粗体中的部分是我目前想出的正则表达式的匹配项:
(?!^),*\s*(?:vol[ume]*\.*)\s*(?=[0-9A-Z]+)

所有都正确,除了最后一个,因为它位于行首,所以不应该包括在内。
据我从http://www.regular-expressions.info/refadv.html 的文档中可以看出,表达式中的(?!^) 环视部分应该排除,*\s*(?:vol[ume]*\.*)\s*(?=[0-9A-Z]+) 在行首找到的匹配项,但这似乎不起作用。

另一方面,表达式(?!^)op[us]*\.*\s*(?=[0-9]+) 可以正常工作,并且不会在以下文本的最后一行返回匹配项:
华尔兹 op. 15
华尔兹作品15
作品 15:华尔兹舞

第一个表达式我做错了什么?

【问题讨论】:

  • 您的第二个正则表达式与最后一行的“opus”匹配。

标签: java regex regex-lookarounds


【解决方案1】:

这就是您的正则表达式没有按预期工作的原因

  • 缺少负向回溯<。应该是(?<!^)
  • lookbehind 应该在 (?:vol[ume]*\.*) 之前立即
  • 您需要启用多行(?m)(没有它^将只匹配输入开始)

所以,你的正则表达式和这些更正变成了

(?m),*\s*(?<!^)(?:vol[ume]*\.*)\s*(?=[0-9A-Z]+)

上述工作,但可以进一步改进。使用[ume]* 也可以匹配voleeevolmeu 等。可以使用?? 设为可选,而不是使用*,.

(?m),?\s*(?<!^)(?:vol\.?|volume)\s*(?=[0-9A-Z]+)

【讨论】:

  • 这个解决方案正是我所需要的。感谢您指出滥用* 以支持?
【解决方案2】:

如果您尝试匹配不在行首的 vol/vol./volume,以下应该可以:

^.+(vol\.?|volume)

^.+ 表示从行首匹配 1 个或多个字符

(vol\.?|volume) 表示匹配 vol 后跟可选的 . 或匹配 volume

【讨论】:

    【解决方案3】:

    与其抗争,不如顺其自然:

    ^.+\s*(?:vol[ume]*\.*)\s*(?=[0-9A-Z]+)
    

    在行首强制匹配 (^),后跟 一个或多个个字符...

    【讨论】:

    • 也会匹配“voleee”、“volmeu”等
    • 明白。因为没有说明完整的要求(是的,在某种程度上可以从正则表达式中推断出来)我只解决了具体问题。
    • 此解决方案选择从行首到 vol 的所有内容。或数量,这与我原来的问题中的要求不符。
    猜你喜欢
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多