【问题标题】:Regexp. How to match word isn't followed and preceded by another characters正则表达式。如何匹配单词后面没有其他字符
【发布时间】:2017-07-26 13:39:35
【问题描述】:

我想在我的代码中将 mm 单位替换为 cm 单位。在大量此类替换的情况下,我使用regexp

我做了这样的表达:

(?!a-zA-Z)mm(?!a-zA-Z)

但它仍然匹配 summagammadummy 等词。

如何正确组成正则表达式?

【问题讨论】:

  • 使用lookahead/lookbehind代替\b[0-9+]\s?mm\b之类的东西有什么好处吗?

标签: regex


【解决方案1】:

使用字符类并将第一个(?!...)lookahead 更改为lookbehind:

(?<![a-zA-Z])mm(?![a-zA-Z])
^^^^^^^^^^^^^   ^^^^^^^^^^^ 

regex demo

模式匹配:

  • (?&lt;![a-zA-Z]) - 如果当前位置的左侧有一个 ASCII 字母,则匹配失败
  • 的否定lookbehind
  • mm - 文字子串
  • (?![a-zA-Z]) - 如果当前位置的右侧有一个 ASCII 字母,则匹配失败

注意:如果您需要让您的模式识别 Unicode,请将 [a-zA-Z] 替换为 [^\W\d_](如果您使用的是 Python 2.x,请使用 re.U 标志)。

【讨论】:

  • 由于并非所有浏览器都支持lookarounds,如何修改它以避免使用lookaheads或lookbehinds但仍能获得所需的结果?
  • @Arsik36 在大多数情况下,可以使用一些代码和稍微修改的模式来解决缺少后视的问题。例如。 (^|[^a-zA-Z])mm(?![a-zA-Z])。但是你可以试试单词边界,\bmm\b
  • 感谢您的回答。我学习正则表达式时的一个新手问题,正则表达式的哪一部分指定在 mm 之前不能有 ASCII 字母?是指定它的 ^ 符号吗?还有你为什么要包含 OR 符号,这解决了什么边缘情况?
  • @Arsik36 你问错了问题。你的输入是什么?你的预期输出是什么?什么是编程环境?
  • @Arsik36 那么单词边界可能就足够了,\blocal\b,或者像我展示的那样的解决方案,[^a-zA-Z\d]local\b。您不需要任何更改,因为 local 永远不会出现在字符串的开头((^|[^A-Za-z]) 匹配字符串的开头或除 ASCII 字母之外的任何字符)。
【解决方案2】:

没有必要使用前瞻和后瞻,所以如果你想简化你的模式,你可以尝试这样的事情;

\d+\s?(mm)\b

这确实假设您的毫米符号将始终跟随一个数字,中间有一个可选的空格,我认为在这种情况下这是一个合理的假设。

\b 检查单词边界以确保 mm 不是诸如 dummy 等单词的一部分。

Demo here

【讨论】:

    猜你喜欢
    • 2017-07-26
    • 2017-10-27
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    相关资源
    最近更新 更多