例如,我的文字有很多产品尺寸,例如“2x4”,我想将其转换为“2 x 4”。
pattern = r"([0-9])\s*[xX\*]\s*([0-9])"
re.sub(pattern, r"\1 xby \2", "2x4")
'2 xby 4' # good
re.sub(pattern, r"\1 xby \2", "2x4x12")
'2 xby 4x12' # not good. need this to be '2 xby 4 xby 12'
描述我想要做的事情的一种方法是重复替换,直到不能再进行替换。例如,我可以简单地对上面的替换进行两次以获得我想要的东西
x = re.sub(pattern, r"\1 xby \2", "2x4x12")
x = re.sub(pattern, r"\1 xby \2", x)
'2 xby 4 xby 12'
但我认为有更好的方法
答案 0 :(得分:5)
您可以使用此前瞻性正则表达式进行搜索:
r'([0-9]+)\s*[xX*]\s*(?=[0-9]+)'
(?=[0-9]+)
是一个积极的先行者,只是通过向前看来断言存在第二个数字,但是不会通过匹配数字来移动内部正则表达式指针。
并将其用于替换:
r'\1 xby '
<强>代码:强>
>>> pattern = r'([0-9]+)\s*[xX*]\s*(?=[0-9]+)'
>>> re.sub(pattern, r'\1 xby ', "2x4")
'2 xby 4'
>>> re.sub(pattern, r'\1 xby ', "2x4x12")
'2 xby 4 xby 12'
答案 1 :(得分:1)
我认为你可以通过一次通过来解决这个问题。你真正想要做的是用xby替换x - 所以你可以扫描整个字符串一次,如果你不消耗数字的右边。
为此,我建议使用前瞻性断言。基本上,确认您要替换的东西后跟数字,但不要吃过程中的数字。这种表示法是(?= ...) - 见re docpage。
对我来说,我有以下内容 - 请注意,编译正则表达式是可选的,\ d通常优先于[0-9]:
pattern = re.compile(r"(\d+)\s*[xX\*]\s*(?=\d)")
pattern.sub(r"\1 xby ", "2x4x12")
'2 xby 4 xby 12'
在一次传递中,它将处理整个字符串。
答案 2 :(得分:0)
由于您正在尝试针对已由正则表达式转换的文本重新运行匹配,因此实际上并没有更好的方法。
这有点像解开数学问题,如果你想这样做:(2 + 3)+ 4,你需要更换&#34;(2 + 3)&#34 ;能够取代&#34; 5 + 4&#34;因为字符串&#34; 5&#34;原文中没有任何内容。
您可能想要做的是测试您的字符串是否有任何匹配,并继续在之前的结果中重新运行替换,直到找不到更多匹配项。
编辑:您也可以为重复次数制作一些正则表达式,并按长度的降序运行它们。即寻找2x3x5x2然后2x3x5然后2x3,因为逐渐地你不会击中任何已被替换的东西。