【问题标题】:Regex for matching substring, but not containing word用于匹配子字符串但不包含单词的正则表达式
【发布时间】:2015-01-08 04:33:05
【问题描述】:

我希望能够使用正则表达式来匹配给定的字符串,而不是包含它的特定更长的单词。这是一个更好地解释的例子:

给定文字:

String bellsringing = "The bells are ringing is a String";

我希望能够找到“ring”的所有出现,它们不属于单词 String 的一部分,不限于单词(可以出现在一个里面)。 所以答案只会是“铃声(铃声)”和“(铃声)铃声”。

我知道一个程序可以用于这样的任务,但是我遇到了在大型库中查找特定字符串的需要,如果寻找的字符串是一个公共关键字/文字的子字符串,我有很多使用正则表达式函数进行挖掘并将受益于 IDE 的搜索:)

感谢您对此的任何意见。

【问题讨论】:

  • 谢谢,但这并不能解决我的问题。
  • “字符串”是您要排除的唯一文本吗?还是像“带来”之类的东西?您可以使用word boundaries 来匹配单词的开头或结尾,但是区分在某些单词中间而不是其他单词 可能真的很麻烦。
  • 看看this answer 了解除了上下文A、B或C之外如何捕获字符串。正则表达式无法理解单词中的一组字母是否保留了它的含义,因此您必须以某种方式列出使用此上下文 A、B 或 C 技术可以接受和不接受的内容。这是 Fede 答案的长版本。
  • 哇...感谢您的链接。这让我很开心。现在我也理解了@Fede 的回答 :)

标签: regex


【解决方案1】:

PCRE(Perl 兼容正则表达式)

如果您使用的是PCRE 正则表达式,那么您可以使用这样的正则表达式:

String(*SKIP)(*FAIL)|ring

Working demo

这个正则表达式的想法是失败string 模式,所以它会跳过它但会保留ring。顺便说一句,如果你想获取完整的单词,你可以使用这个正则表达式:

String(*SKIP)(*FAIL)|(\w*ring\w*)

匹配信息为:

MATCH 1
1.  [14-21] `ringing`
MATCH 2
1.  [64-71] `ringing`

其他引擎

另一方面,如果你不使用PCRE,你可以利用丢弃模式,这是一个非常好的正则表达式技巧:

String|(\w*ring\w*)

Working demo

在这种情况下,您所做的就是匹配模式左侧不想要的,而在最右侧保留您想要的使用一个组。丢弃模式遵循以下规则:

discard patt1 | discard patt2 | ... | discard pattN | (KEEP THIS PATTERN)

然后你必须访问正则表达式组\1$1 来获取保存的字符串。对于这种情况是:

MATCH 1
1.  [14-21] `ringing`
MATCH 2
1.  [64-71] `ringing`

Debuggex 很好地以图形方式显示这种技术:

【讨论】:

  • 感谢@funkwurm 的评论,我理解您的回答,非常好。然而,这对文本编辑器或 IDE 的查找和替换功能没有帮助,因为它们会查看所有匹配的组,因此它也匹配 String。
  • 结合@OnlineCop 的评论,这确实有效:) 谢谢,伙计们
  • @AdrianB。是的,这就是丢弃技术的缺点。我专注于编程而不是文本编辑器,因为这种技术是一个弱点。
  • 我在演示中得到 4 个匹配项,2 个用于响铃,2 个用于字符串
【解决方案2】:
String|\b(\w*?ring\w*)\b

试试这个。抓住捕获。查看演示。应用i 标志。

http://regex101.com/r/tF5fT5/39

【讨论】:

    【解决方案3】:

    根据@Fede 的回答,使用否定的前瞻:

    \b(?!String)\w*ring\w*\b
    

    这将从单词边界开始,确保它找不到String,然后在可以找到的地方匹配ring

    Working example

    【讨论】:

    • 接受@Fede 的回答,因为它更详细,但这是一个赞成
    • OnlineCop 很聪明,我喜欢你的方法+1
    • 是的;如果我对此投赞成票,我会感到难过; Fede 的回答非常彻底(我什至从中学到了一些新东西)。 :-D
    • 大声笑,不要这样做。您的答案是有效且好的答案,并显示了一种不同的方法。我也向你学习。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2010-10-26
    相关资源
    最近更新 更多