正则表达式:匹配空格之间的单词

7

我试图在Python中使用正则表达式来做一件相当简单的事情...至少我是这么认为的。

我的目标是:如果一个单词前后都有空格,那么匹配该字符串中的单词。如果该单词位于字符串的开头,则不需要空格 - 如果该单词位于字符串的末尾,则也不需要搜索空格。

例如:

"WordA WordB WordC-WordD WordE"

我想匹配 WordA WordB WordE

我只想到了过于复杂的方法...

(?<=(?<=^)|(?<=\s))\w+(?=(?=\s)|(?=$))

我觉得对于这样一个简单的问题,一定有一个简单的方法......我想我可以从(?<=\s|^)开始,但似乎不可能,因为“后顾之忧需要固定宽度模式”。
1个回答

9

看起来您在使用Python,因为在PCRE、Java和Ruby中(?<=^|\s)是完全有效的(而.NET正则表达式支持无限宽度的后顾模式)。

使用:

(?<!\S)\w+(?!\S)

这将匹配一个或多个由空格或字符串开头/结尾包围的单词字符。

请参见正则表达式演示

模式详细信息

  • (?<!\S) - 一个否定回顾,一旦引擎发现当前位置左侧有非空格字符,则匹配失败
  • \w+ - 一个或多个单词字符
  • (?!\S) - 一个否定前瞻,一旦引擎发现当前位置右侧有非空格字符,则匹配失败。

有道理!谢谢。我猜查找非空格而不是空格要容易得多。 - SyntaxError
不确定它是否更容易,但更有效率。 - Wiktor Stribiżew
我不明白为什么简单地用\s+包围我们需要的内容就不能起作用。 - B Furtado
1
@BFurtado 因为\s会匹配一个空格。可以看一下这个演示:只有一个匹配,因为两端的\s 必须 在左右两边都有一个空格。WordAWordE一端没有空格。你可能认为 (\s|^)\w+(\s|$) 可以解决问题,但是它不能匹配连续出现的单词,因为 (\s|$) 消耗了 WordA 后面的空格,所以 (\s|^) 无法匹配到 WordB 的匹配。 - Wiktor Stribiżew
非常感谢@WiktorStribiżew。我曾经无数次地与正则表达式斗争过。官方文档https://docs.python.org/3/howto/regex.html没有提到消耗空格的内容。有关零宽度的描述相当晦涩(对我来说似乎不太相关),但可能类似于您友善解释的内容。最好的祝福, - B Furtado
1
@BFurtado 我会在我的Youtube频道上尝试解释它,并与您分享链接(频道链接在我的个人资料中)。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接