繁体   English   中英

是否有单个Python正则表达式可以将以“#”开头的行上的所有“ foo”更改为“ bar”?

[英]Is there a single Python regex that can change all “foo” to “bar” on lines starting with “#”?

是否可以编写一个可以应用于多行字符串的Python正则表达式,并将所有出现的“ foo”更改为“ bar”,但只能在以“#”开头的行上进行编写?

我能够使用Perl的\\ G正则表达式sigil使其在Perl中工作,该正则表达式sigil与上一场比赛的结尾相匹配。 但是,Python似乎不支持此功能。

如果有帮助,这是Perl解决方案:

my $x =<<EOF;
# foo
foo
# foo foo
EOF

$x =~ s{
        (            # begin capture
          (?:\G|^\#) # last match or start of string plus hash
          .*?        # followed by anything, non-greedily
        )            # end capture
        foo
      }
      {$1bar}xmg;

print $x;

正确的输出,当然是:

# bar
foo
# bar bar

可以用Python完成吗?


编辑:是的,我知道可以将字符串分成几行并测试每一行,然后决定是否应用转换,但是请我相信在这种情况下这样做并非易事。 我确实确实需要使用单个正则表达式来做到这一点。

lines = mystring.split('\n')
for line in lines:
    if line.startswith('#'):
        line = line.replace('foo', 'bar')

无需正则表达式。

使用正则表达式看起来很容易:

>>> import re
... text = """line 1
... line 2
... Barney Rubble Cutherbert Dribble and foo
... line 4
... # Flobalob, bing, bong, foo and brian
... line 6"""
>>> regexp = re.compile('^(#.+)foo', re.MULTILINE)
>>> print re.sub(regexp, '\g<1>bar', text)
line 1
line 2
Barney Rubble Cutherbert Dribble and foo
line 4
# Flobalob, bing, bong, bar and brian
line 6

但是,然后尝试您的示例文本不是很好:

>>> text = """# foo
... foo
... # foo foo"""
>>> regexp = re.compile('^(#.+)foo', re.MULTILINE)
>>> print re.sub(regexp, '\g<1>bar', text)
# bar
foo
# foo bar

因此,请尝试以下操作:

>>> regexp = re.compile('(^#|\g.+)foo', re.MULTILINE)
>>> print re.sub(regexp, '\g<1>bar', text)
# foo
foo
# foo foo

似乎可行,但是我在文档中找不到\\ g!

道德:不要在喝了几杯啤酒之后尝试编码。

\\ g和perl一样在python中工作,并且在docs中

“除了如上所述的字符转义和反向引用外,\\ g将使用与名称组匹配的子字符串,名称组的名称由(?P ...)语法定义。\\ g使用​​相应的组号; \\ g <2因此>等效于\\ 2,但在诸如\\ g <2> 0之类的替换中并没有歧义。\\ 20将被解释为对组20的引用,而不是对组2的引用,后跟文字字符'0 '。后向引用\\ g <0>替换RE匹配的整个子字符串。”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM