1

我通过使用单词边界在 python 正则表达式中尝试了单独的 m 并找到它们。这些 m 应该在两边都有一个空格或开始/结束字符串:

r = re.compile("\\bm\\b")
re.findall(r, someString)

但是,这种方法也可以在单词中找到 m,I'm因为撇号被认为是单词边界。如何编写不将撇号视为单词边界的正则表达式?

我试过这个:

r = re.compile("(\\sm\\s) | (^m) | (m$)")
re.findall(r, someString)

但这与任何 m 都不匹配。奇怪的。

4

3 回答 3

3

使用环视断言:

>>> import re
>>> re.findall(r'(?<=\s)m(?=\s)|^m|m$', "I'm a boy")
[]
>>> re.findall(r'(?<=\s)m(?=\s)|^m|m$', "I m a boy")
['m']
>>> re.findall(r'(?<=\s)m(?=\s)|^m|m$', "mama")
['m']
>>> re.findall(r'(?<=\s)m(?=\s)|^m|m$', "pm")
['m']

(?=...)

如果下一个匹配则...匹配,但不消耗任何字符串。这称为前瞻断言。例如,Isaac 仅在其后跟. 时(?=Asimov)才会匹配。'Isaac ''Asimov'

(?<=...)

如果字符串中的当前位置前面有匹配,则匹配...在当前位置结束。这称为肯定的后向断言。将在, ...(?<=abc)def中找到匹配项abcdef

正则表达式语法

顺便说一句,使用原始字符串 ( r'this is raw string'),您不需要 escape \

>>> r'\s' == '\\s'
True
于 2013-10-12T06:51:14.823 回答
1

您甚至不需要环顾四周(除非您想捕获没有空格的 m ),但您的第二个示例距离几英寸。是额外的空格(在 python 中可以,但不在正则表达式中)使它们不起作用:

>>> re.findall(r'\sm\s|^m|m$', "I m a boy")
[' m ']
>>> re.findall(r'\sm\s|^m|m$', "mamam")
['m', 'm']
>>> re.findall(r'\sm\s|^m|m$', "mama")
['m']
>>> re.findall(r'\sm\s|^m|m$', "I'm a boy")
[]
>>> re.findall(r'\sm\s|^m|m$', "I'm a boym")
['m']
于 2013-10-12T07:35:59.667 回答
1

falsetru 的答案几乎等同于“\b 除了撇号”,但不完全是。它仍然会找到缺少边界的匹配项。使用 falsetru 的示例之一:

>>> import re
>>> re.findall(r'(?<=\s)m(?=\s)|^m|m$', "mama")
['m']

它找到了 'm',但在 'mama' 中没有出现匹配 '\bm\b' 的 'm'。第一个 'm' 匹配 '\bm',但这是最接近的。

实现“\b without apostrophes”的正则表达式如下所示:

(?<=\s)m(?=\s)|^m(?=\s)|(?<=\s)m$|^m$

这将找到以下 4 种情况中的任何一种:

  1. 'm' 前后有空格
  2. 'm' 开头,后跟空格
  3. 'm' 结尾,前面有空格
  4. 'm' 前面或后面没有任何内容(即字面意义上的字符串“m”)
于 2016-09-02T17:13:48.067 回答