考虑Python代码段:
import re
str = 'that that kitty is cute'
# Anchor at beginning of string
rgexp_start = r'^(.*) \1'
print(re.sub(rgexp_start, r'\1', str))
# Do NOT anchor at beginning of string
rgexp = r'(.*) \1'
print(re.sub(rgexp, r'\1', str))
打印:
that kitty is cute
thatkittyiscute
为什么第二个正则表达式会删除所有空格?还有一个问题,请考虑JavaScript代码段:
var str = 'that that kitty is cute';
var rgexp_start = /^(.*) \1/;
alert(str.replace(rgexp_start, '$1'));
var rgexp = /(.*) \1/;
alert(str.replace(rgexp, '$1'));
哪两次给出:
that kitty is cute
为什么JavaScript在处理相同的正则表达式时与Python不同?
答案 0 :(得分:3)
要回答您的第一个问题,re.sub
将完全替换您传递的模式。
因此,r'^(.*) \1'
表示替换从头开始的所有重复项。由于您已指定匹配从头开始,并且因为字符串只有一个开头,因此唯一可以找到匹配和替换的是'^that that'
,因此它已完成。
In[]: 'that that kitty is cute'
'^that that' -> 'that'
Out[]: 'that kitty is cute'
如果是r'(.*) \1'
,.*
实际上可以匹配 0个或更多字符。这很重要,因为现在正则表达式不再受限于开始了。所以它的作用是,'^that that
' (第一个正则表达式也是这样),它匹配''
,然后是空格,然后是''
,再次匹配,共3次。因此,它会用' '
替换''
(两边都有''
(空字符串)的空格)。
In[]: 'that that kitty is cute'
'that that' -> 'that'
' ' -> ''
' ' -> ''
' ' -> ''
Out[]: 'thatkittyiscute'
要回答你的第二个问题,不同的是b / w python和JS,正如anubhava所解释的那样,JS中的全局标志默认不启用;只发生第一次更换,保持字符串的其余部分不受影响。
答案 1 :(得分:2)
Javascript行为不同,因为您没有在Javascript正则表达式中打开global
或g
标记(默认情况下在python中打开)。
如果您使用带g
标记的相同正则表达式:
var rgexp = /(.*) \1/g;
console.log(str.replace(rgexp, '$1'));
然后会打印出来:
thatkittyiscute
与python
的行为相同。
顺便说一句,如果你使用这个略有不同的正则表达式:
(\S+) \1
然后,即使没有锚,也会在更换后始终打印出来,如第一个例子所示:
that kitty is cute
\S+
匹配一个或多个非空白字符。