正则表达式:匹配单词不在引号之间

时间:2016-12-14 08:31:29

标签: python regex string quote

我想要一个Python正则表达式,它匹配不在简单引号之间的给定单词。我试过使用(?! ...)但没有成功。

在下面的屏幕截图中,我想匹配除第4行之外的所有foe

另外,文本是一个大字符串。

以下是链接regex101,示例文字如下:

var foe = 10;
foe = "";
dark_vador = 'bad guy'
foe = ' I\'m your father, foe ! '
bar = thingy + foe

5 个答案:

答案 0 :(得分:1)

this正则表达式怎么样:

>>> s = '''var foe = 10;
foe = "";
dark_vador = 'bad guy'
' I\m your father, foe ! '
bar = thingy + foe'''
>>>
>>> re.findall(r'(?!\'.*)foe(?!.*\')', s)
['foe', 'foe', 'foe']

这里的诀窍是确保表达式与前导和尾随'的任何字符串都不匹配,并记住在其中记住之间的字符,其后是重新表达式中的.*

答案 1 :(得分:1)

你可以试试这个: -

((?!\'[\w\s]*)foe(?![\w\s]*\'))

答案 2 :(得分:1)

enter image description here

((?!\'[\w\s]*[\\']*[\w\s]*)foe(?![\w\s]*[\\']*[\w\s]*\'))

答案 3 :(得分:1)

下面的正则表达式解决方案在大多数情况下都有效,但如果不平衡的单引号出现在字符串文字之外,它可能会中断,例如在评论中。

在上下文中匹配字符串的常用正则表达技巧是匹配您需要替换和匹配的内容以及捕获您需要保留的内容。

以下是Python演示示例:

import re
rx = r"('[^'\\]*(?:\\.[^'\\]*)*')|\b{0}\b"
s = r"""
    var foe = 10;
    foe = "";
    dark_vador = 'bad guy'
    foe = ' I\'m your father, foe ! '
    bar = thingy + foe"""
toReplace = "foe"
res = re.sub(rx.format(toReplace), lambda m: m.group(1) if m.group(1) else 'NEWORD', s)
print(res)

请参阅Python demo

正则表达式看起来像

('[^'\\]*(?:\\.[^'\\]*)*')|\bfoe\b

请参阅regex demo

('[^'\\]*(?:\\.[^'\\]*)*')部分将单引号字符串文字捕获到第1组中,如果匹配,则只返回结果,\bfoe\b匹配任何其他字符foe字符串上下文 - 随后被另一个单词替换。

注意:要匹配双引号字符串文字,请使用r"('[^'\\]*(?:\\.[^'\\]*)*'|\"[^\"\\]*(?:\\.[^\"\\]*)*\")"

答案 4 :(得分:0)

以下正则表达式的捕获组1将包含'foe'的匹配项。

r'^(?:[^'\n]|\\')*(?:(?<!\\)'(?:[^'\n]|\\')*(?:(?<!\\)')(?:[^'\n]|\\')*)*\b(foe)\b'

Start your engine!

Python的正则表达式引擎执行以下操作。

^           : assert beginning of string
(?:         : begin non-capture group
  [^'\n]    : match any char other than single quote and line terminator
  |         : or
  \\'       : match '\' then a single quote
)           : end non-capture group   
*           : execute non-capture group 0+ times
(?:         : begin non-capture group
  (?<!\\)   : next char is not preceded by '\' (negative lookbehind)
  '         : match single quote
  (?:       : begin non-capture group
    [^'\n]  : match any char other than single quote and line terminator
    |       : or
    \\'     : match '\' then a single quote
  )         : end non-capture group   
  *         : execute non-capture group 0+ times
  (?:       : begin non-capture group
    (?<!\\) : next char is not preceded by '\' (negative lookbehind)
    '       : match single quote
  )         : end non-capture group
  (?:       : begin non-capture group
    [^'\n]  : match any char other than single quote and line terminator
    |       : or
    \\'     : match '\' then a single quote
  )         : end non-capture group   
  *         : execute non-capture group 0+ times
)           : end non-capture group
*           : execute non-capture group 0+ times
\b(foe)\b   : match 'foe' in capture group 1