【问题标题】:Regex using word boundary but word ends with a . (period)正则表达式使用单词边界但单词以 . (时期)
【发布时间】:2013-08-01 21:29:52
【问题描述】:

想匹配单词i.v.不区分大小写

有模式

(?i)\bi\.v\.

但要在末尾有一个单词边界
上述模式失败,因为它匹配
i.v.x

但如果我尝试在末尾添加工作边界

(?i)\bi\.v\.\b

它失败了,因为它甚至不匹配 i.v。 因为我认为\b 正在吃字面意思。作为 。是一个分词
需要\. 贪婪

我想匹配
山姆 i.v.山姆

不想匹配
sam.i.v.
i.v.sam

这里越来越近了

(?i)\bi\.v\.\s$

但它无法找到 i.v.在一行的末尾

【问题讨论】:

  • 你的问题是什么?为什么要在表达式末尾添加\b?当允许匹配时,这个i.v. 字符串后面会出现什么?
  • @Qtax 因为我只想要一个单词匹配。第一个模式将匹配 i.v.x.
  • 你想匹配“i.v.x”,但不匹配“xxi.v.x”?那么“i.v. x”(. 和 x 之间有一个空格)呢?
  • @JimMischel 是的,我想匹配空间。这就是我所说的词的意思。我应该更清楚。
  • 你为什么不想找到sam.i.v.?因为i.v.前面没有空格?那么单词边界是错误的工具。

标签: .net regex


【解决方案1】:

\b 仅匹配字母数字字符和非字母数字字符(或字符串的开头/结尾)。因此,它在 . 之后不匹配,除非该点后面紧跟一个字母数字字符。

如果您的意图是确保在点之后没有非空白字符,那么您可以使用negative lookahead assertion 指定:

(?i)\bi\.v\.(?!\S)

(?!\S) 表示“断言下一个字符不是非空白字符”。

这听起来有点令人费解——为什么要双重否定?为什么不(?=\s) 表示“断言下一个字符是空白字符”?嗯,有一个微妙的区别:第二个版本需要一个空白字符。这意味着正则表达式将无法在字符串末尾匹配。第一个正则表达式也处理这种极端情况。

如果您通常希望“单词边界”的概念表示“空格分隔”,那么您还需要替换第一个\b

(?i)(?<!\S)i\.v\.(?!\S)

否则正则表达式将匹配您似乎不想要的sam.i.v.

【讨论】:

  • 您最近对您的问题所做的编辑让我有点困惑(我只是在写完答案后才阅读它)-我已经对您的问题发表了评论,您能看一下吗?我认为您还需要替换第一个单词边界...
  • 我同意。 \b 匹配 ?i.v.
  • 我不知道它是如何工作的,但我很高兴上帝创造了像你这样的人。谢谢蒂姆。
【解决方案2】:

关于你当前的正则表达式:

你不需要在点之后有\b,因为点不被认为是一个单词字符,但当然点需要被转义:

(?i)\bi\.v\.

但您确实需要在 i 之前使用 \b 以确保它不匹配,例如hi

编辑:(基于您的进一步编辑)

试试这个正则表达式:

(?i)\bi\.v\.(?=\s|$)

【讨论】:

  • 在 sam i.v. 上失败山姆
  • 这是我的问题,作为我想要匹配的样本
  • 是的,它会匹配(抱歉,我在您之前的评论中没有看到sam 之前的空格;眼睛累了!这里已经很晚了)无论如何,请检查我提供的演示,我相信它适用于你所有的案例。
【解决方案3】:

您似乎对单词边界和贪婪的概念非常困惑。你能做的最好的事情就是去这些地址:

  • 什么是贪心量词:

http://www.regular-expressions.info/repeat.html

  • 什么是词边界:

http://www.regular-expressions.info/wordboundaries.html

当您阅读这些解释时,我相信您会认为您的问题很荒谬。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 2012-09-24
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    相关资源
    最近更新 更多