【问题标题】:Regex Lookahead and Lookbehinds: followed by this or thatRegex Lookahead 和 Lookbehinds:后跟这个或那个
【发布时间】:2013-05-30 15:43:40
【问题描述】:

我正在尝试编写一个正则表达式,它会提前检查以确保在我正在搜索的单词之后有一个空格字符或一个左括号。 另外,我希望它回顾并确保它前面有一个非单词 (\W) 或什么都没有(即它是语句的开头)。

到目前为止,

"(\\W?)(" + words.toString() + ")(\\s | \\()"

但是,这也匹配两端的东西 - 我希望这个模式只匹配单词本身 - 而不是它周围的东西。

我正在使用 Java 风格的正则表达式。

【问题讨论】:

  • 如果该正则表达式匹配一个字符串,它将有 4 个groups。第一个将是整个字符串,第三个将是您要查找的单词。

标签: java regex regex-lookarounds


【解决方案1】:

当您自己标记问题时,您需要lookarounds

String regex = "(?<=\\W|^)(" + Pattern.quote(words.toString()) + ")(?= |[(])"
  • (?&lt;=X) 表示 “前面有 X”
  • (?&lt;!=X) 表示 " 前面有 X"
  • (?=X) 表示 “后跟 X”
  • (?!=X) 表示 "不是 后跟 X"

【讨论】:

  • 在将一些纯字符串插入正则表达式时,始终使用Pattern.quote()。而(?&lt;=\\W|^) 可以缩短为(?!\w)。还要注意(?= |[(]) 应该是(?= | [(])
  • @nhahtdh 你能举一个Pattern.quote()的例子吗?我不确定你的意思
  • 你能提供words.toString()的输出吗?
  • 查看文档,Pattern.quote(String)。它会在将字符串插入模式之前转义字符串中的元字符。
【解决方案2】:

单词本身呢:它总是以单词字符开头(即匹配\w的字符)吗?如果是这样,您可以使用词边界作为前导条件。

"\\b" + theWord + "(?=[\\s(])"

否则,您可以使用否定的lookbehind:

"(?<!\\w)" + theWord + "(?=[\\s(])"

我假设这个词是这样引用的:

String theWord = Pattern.quote(words.toString());

...或者不需要。

【讨论】:

    【解决方案3】:

    如果您不希望某个组被匹配捕获,您可以使用特殊构造(?:X)

    所以,在你的情况下:

    "(?:\\W?)(" + words.toString() + ")(?:\\s | \\()"
    

    那么您将只有两个组,group(0) 用于整个字符串,group(1) 用于您要查找的单词。

    【讨论】:

    • 我相信问题不在于 capturing 而是 matching(?:) 不会捕获该组,但仍会匹配。
    • 这是词汇混乱。 OP想要匹配一个前面有一些构造C1和后面跟着一些构造C2的单词,并且只得到介于两者之间的单词。他可以通过在您的答案中使用环视来做到这一点,或者通过匹配整个事情并像我一样获得他想要的位。结果是一样的,我认为OP的问题是关于获取数据,而不是如何使用特定的技术,但我可能弄错了。
    • @CyrilleKa 你是对的;我只想提取我需要的数据,如果最好的方法不是使用环视,那也很好。但是,您的答案对我不起作用...
    • 你必须告诉我们更多关于它是如何不工作的。例如,发布SSCCE,告诉我们您的期望和获得的结果。
    • 好吧,我正在创建一个名为 regexString,从上面使用你的,里面的单词是 hello|goodbye。我在这里将它作为参数传递:Pattern.compile(regex) 然后我通过pattern.matcher("hello yo and BIGhello and have a goodbye") 创建一个匹配器。当我用matcher.find() 运行一个while 循环时,它什么也找不到。
    猜你喜欢
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2015-09-22
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    相关资源
    最近更新 更多