Python re.sub 如何将字符串中的每个 0 替换为 2,当它旁边没有 1 时?
Python re.sub How to replace every 0 in a string with a 2 when there is no 1 directly next to it?
我对正则表达式完全陌生,现在我有以下任务:
我有一个看起来像这样的字符串:001000X00X001X00X
现在我想用 2 替换每个 0,当它旁边没有 1 且没有被 X 分隔时,因此示例字符串应更改为:001000X22X001X22X
我尝试使用类似这样的东西来做到这一点:
s = re.sub(r'X0+X', 'X2+X', s);
所以它搜索以 X 开头和结尾的子字符串,并且之间有一个随机数的“0”,但显然每个像这样的子字符串都被更改为 'X2+X'。
如何计算 0 的个数并将每个 0 替换为 2?
你可以使用
import re
s = '001000X00X001X00X'
print( re.sub(r'(?<=X)0+(?=X)', lambda x: '2' * len(x.group()), s) )
# => 001000X22X001X22X
## Or, if you also want to match start/end of string positions:
print( re.sub(r'(?<![^X])0+(?![^X])', lambda x: '2' * len(x.group()), s) )
# => 001000X22X001X22X
参见Python demo。 详情:
(?<=X)0+(?=X)
匹配一个或多个 0
字符,当此文本块紧跟在 X
字符 之前和之后
(?<![^X])0+(?![^X])
- 匹配一个或多个 0
字符,这些字符以 X
或字符串开头并后跟 X
或字符串结尾
- 一旦匹配,匹配的文本将替换为相同数量的
2
个字符。
使用 PyPi regex
模块(使用 pip install regex
安装在 terminal/console 中)您可以使用更简洁的
import regex
s = '00X00'
print( regex.sub(r'(?<=(?:^|X)0*)0(?=0*(?:X|$))', '2', s) )
# => 22X22
参见 this Python demo and this regex demo。
(?<=(?:^|X)0*)0(?=0*(?:X|$))
正则表达式匹配
(?<=(?:^|X)0*)
- 紧接 X
或字符串开头的位置,然后是零个或多个 0
个字符
0
- 零
(?=0*(?:X|$))
- 紧跟零个或多个 0
个字符的位置,然后是 X
或字符串结尾。
我提供正则表达式答案的速度太慢(@Wiktor Stribiżew,你太快了!),所以这里有一个使用拆分字符串作为中间值的替代方法:
'X'.join([re.sub('0', '2', i) if not '1' in i else i for i in s.split('X')])
如果字符串仅包含 0/1/X,这将是一个 simpler/faster 替代方案:
'X'.join(['2'*len(i) if not '1' in i else i for i in s.split('X')])
注意。在@JvdV 的评论之后,这是对@WiktorStribiżew 的回答的修正:
re.sub(r'(?<=X)0+(?=X)', lambda x: '2'*len(x.group()), 'X'+s+'X')[1:-1]
输出:'22X001000X22X001X22X'
您可以匹配 X
后跟 1 次或多次以查看右侧的 X
结尾的零,然后用 2
替换所有零
import re
pattern = r"X0+(?=X)"
s = "001000X00X001X00X"
print(re.sub(pattern, lambda x: x.group().replace('0', '2'), s))
输出
001000X22X001X22X
如果您还想匹配 X
之前或之后的开头和结尾处的零,字符串的开头或结尾:
(?:X0+|^0+)(?=X|$)
import re
strings = [
"0X001000X00X001X00X0",
"001000X00X001X00X",
"000X000",
"000"
]
pattern = r"(?:X0+|^0+)(?=X|$)"
for s in strings:
print(re.sub(pattern, lambda x: x.group().replace('0', '2'), s))
输出
2X001000X22X001X22X2
001000X22X001X22X
222X222
222
我对正则表达式完全陌生,现在我有以下任务:
我有一个看起来像这样的字符串:001000X00X001X00X
现在我想用 2 替换每个 0,当它旁边没有 1 且没有被 X 分隔时,因此示例字符串应更改为:001000X22X001X22X
我尝试使用类似这样的东西来做到这一点:
s = re.sub(r'X0+X', 'X2+X', s);
所以它搜索以 X 开头和结尾的子字符串,并且之间有一个随机数的“0”,但显然每个像这样的子字符串都被更改为 'X2+X'。 如何计算 0 的个数并将每个 0 替换为 2?
你可以使用
import re
s = '001000X00X001X00X'
print( re.sub(r'(?<=X)0+(?=X)', lambda x: '2' * len(x.group()), s) )
# => 001000X22X001X22X
## Or, if you also want to match start/end of string positions:
print( re.sub(r'(?<![^X])0+(?![^X])', lambda x: '2' * len(x.group()), s) )
# => 001000X22X001X22X
参见Python demo。 详情:
(?<=X)0+(?=X)
匹配一个或多个0
字符,当此文本块紧跟在X
字符 之前和之后
(?<![^X])0+(?![^X])
- 匹配一个或多个0
字符,这些字符以X
或字符串开头并后跟X
或字符串结尾- 一旦匹配,匹配的文本将替换为相同数量的
2
个字符。
使用 PyPi regex
模块(使用 pip install regex
安装在 terminal/console 中)您可以使用更简洁的
import regex
s = '00X00'
print( regex.sub(r'(?<=(?:^|X)0*)0(?=0*(?:X|$))', '2', s) )
# => 22X22
参见 this Python demo and this regex demo。
(?<=(?:^|X)0*)0(?=0*(?:X|$))
正则表达式匹配
(?<=(?:^|X)0*)
- 紧接X
或字符串开头的位置,然后是零个或多个0
个字符0
- 零(?=0*(?:X|$))
- 紧跟零个或多个0
个字符的位置,然后是X
或字符串结尾。
我提供正则表达式答案的速度太慢(@Wiktor Stribiżew,你太快了!),所以这里有一个使用拆分字符串作为中间值的替代方法:
'X'.join([re.sub('0', '2', i) if not '1' in i else i for i in s.split('X')])
如果字符串仅包含 0/1/X,这将是一个 simpler/faster 替代方案:
'X'.join(['2'*len(i) if not '1' in i else i for i in s.split('X')])
注意。在@JvdV 的评论之后,这是对@WiktorStribiżew 的回答的修正:
re.sub(r'(?<=X)0+(?=X)', lambda x: '2'*len(x.group()), 'X'+s+'X')[1:-1]
输出:'22X001000X22X001X22X'
您可以匹配 X
后跟 1 次或多次以查看右侧的 X
结尾的零,然后用 2
import re
pattern = r"X0+(?=X)"
s = "001000X00X001X00X"
print(re.sub(pattern, lambda x: x.group().replace('0', '2'), s))
输出
001000X22X001X22X
如果您还想匹配 X
之前或之后的开头和结尾处的零,字符串的开头或结尾:
(?:X0+|^0+)(?=X|$)
import re
strings = [
"0X001000X00X001X00X0",
"001000X00X001X00X",
"000X000",
"000"
]
pattern = r"(?:X0+|^0+)(?=X|$)"
for s in strings:
print(re.sub(pattern, lambda x: x.group().replace('0', '2'), s))
输出
2X001000X22X001X22X2
001000X22X001X22X
222X222
222