【问题标题】:RegEx Extract Sentence with a Matched Word, without stopping at "Mr.", "Mrs." etc正则表达式用匹配的词提取句子,而不会停留在“先生”、“夫人”处等等
【发布时间】:2014-12-09 00:57:23
【问题描述】:

我创建了一个正则表达式,可以提取包含匹配单词的句子。

[^.|?|!]*\<friends\>[^.|!|?]*[\"!?:\.]

但不适用于句子中有Mr./Mrs./Dr.等的情况。

例如:

The adventures are great. I don't know whether you know that Dr. Watson and Mr. Holmes are good friends, Ms. Adler.

我想要的输出是:

I don't know whether you know that Dr. Watson and Mr. Holmes are good friends, Ms. Adler.

如何做到这一点?

【问题讨论】:

  • 在 Debuggex 上查看您的正则表达式,我不确定您是否真的知道它匹配的是什么:debuggex.com/r/YMtOObNo59HHAv8c
  • 例外太多了(不只是标题,还有很多缩写),除非你把它们列出来,否则很难找到一个通用的规则......
  • 另外,您为什么要查找 &lt;friends&gt; 而您的输入不包含 &lt;&gt; 字符?您使用的是哪种语言?
  • @sp00m \ 允许搜索带有连字符的单词,我组成一个:friends-like
  • @DanEng 对不起?我不明白,你有一个预处理器来转换你的正则表达式吗?正则表达式中的\&lt;friends\&gt; 将逐字匹配字符串"&lt;friends&gt;"...

标签: regex


【解决方案1】:

通过负前瞻。

(?:(?!Mr|Ms|Dr|[.?!]).|Mr\.|Ms\.|Dr\.)*\bfriends\b(?:(?!Mr|Ms|Dr|[.?!]).|Mr\.|Ms\.|Dr\.)*[\"!?:.]

DEMO

【讨论】:

  • 我喜欢你的回答,比我的干净多了!对于不支持负前瞻的引擎来说,这是一个缺点,但它是一个干净的解决方案。而且效果很好。
  • 如果真的对你有帮助,你可以考虑accepting
【解决方案2】:

你可以使用这样的东西:(?:(Dr|Mr|Ms)\.|[^.])+ 并且只返回第 1 组匹配的结果。

【讨论】:

    【解决方案3】:

    如果您使用的语言支持 PCRE 风格,这可能是第一个解决方案:

    ((?:[^.?!]|(?&lt;=Mr|Mrs|Ms|Dr)\.)*)friends(?1)

    regex101上的演示和解释

    【讨论】:

    • 我的引擎不支持 PCRE。但感谢您的解决方案!
    【解决方案4】:
    \.((([^.]*Mr\.)|([^.]*Dr\.)|([^.]*Ms\.))*[^.]*)(?<=friends)
    

    这应该可行,您将“朋友”一词更改为您想要在句子中搜索的任何内容,您可以添加更多误报匹配,只需将它们附加在 |([^.]*Ms. ) 以相同的风格,所以如果你也想忽略 M. 你可以添加 |([^.]*M.) 然后正则表达式看起来像这样

    \.((([^.]*Mr\.)|([^.]*Dr\.)|([^.]*Ms\.)|([^.]*M\.))*[^.]*)(?<=friends)
    

    更新的解决方案,现在有点笨拙 :),它保存在捕获组 0 中

    \.(((([^.]*Mr\.)|([^.]*Dr\.)|([^.]*Ms\.)|([^.]*M\.))*[^.]*)(?<=friends)((([^.]*Mr\.)|([^.]*Dr\.)|([^.]*Ms\.)|([^.]*M\.))*[^.!?]*))
    

    【讨论】:

    • 使用第一个正则表达式,输出为:“我不知道你知不知道华生医生和福尔摩斯先生是好朋友” 如何通过昏迷并到达句尾, 如 ?, !还是句号?谢谢。
    • 我有这个:\.((([^.]*Mr\.)|([^.]*Dr\.)|([^.]*Ms\. ))*[^.]*)(?
    【解决方案5】:

    你可以使用这个看起来很糟糕的正则表达式:

    /[a-z](?:(?:(?:drs?|m[rs])\.)|[^.|?|!])*friends(?:(?:(?:drs?|m[rs])\.)|[^.|?|!])*[\"!?:\.]/i
    

    您可以将单词 friends 替换为您想要匹配的任何内容。

    请注意,如果friends 是第一个单词,它不会匹配。

    你可以使用这个,如果friends是第一个单词,则匹配:

    /(?:friends|[a-z])?(?:(?:(?:drs?|m[rs])\.)|[^.|?|!])*friends(?:(?:(?:drs?|m[rs])\.)|[^.|?|!])*[\"!?:\.]/i
    

    这将匹配句子开始之前的空格。

    如果这是一个问题,你可以使用这个:

    /\s*((?:friends|[a-z])?(?:(?:(?:drs?|m[rs])\.)|[^.|?|!])*friends(?:(?:(?:drs?|m[rs])\.)|[^.|?|!])*[\"!?:\.])/i
    

    这会将整个句子保存在 $1 上,并且如果 friends 是第一句,它将起作用。

    所有这些都使用 Javascript 进行了测试,应该适用于其他风格。

    【讨论】:

      猜你喜欢
      • 2014-11-22
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-02
      • 2021-08-15
      相关资源
      最近更新 更多