我有以下字符串输入:
"11A4B"
"5S6B"
并想要以下输出:
["11A", "4B"]
["5S", "6B"]
例如,在每个分隔符 A、B 或 S 拆分并保留分隔符之后。
我可以使用split
from re
(在分隔符模式上加上括号也返回使用的分隔符):
re.split("([ABS])", "11A4B")
#['11', 'A', '4', 'B', '']
并且可以四处寻找想要的解决方案,但我想知道是否有纯正则表达式解决方案?
一种适用于所有 Python 版本的解决方案将是基于 PyPiregex
模块的解决方案,带有regex.split
和regex.V1
标志:
import regex
ss = ["11A4B","5S6B"]
delimiters = "ABS"
for s in ss:
print(regex.split(r'(?<=[{}])(?!$)'.format(regex.escape(delimiters)), s, flags=regex.V1))
输出:
['11A', '4B']
['5S', '6B']
细节
(?<=[ABS])
- 与紧接在前面的位置匹配的正向后视A
,B
或S
(?!$)
- 并且字符串结尾不会立即跟随(因此,字符串末尾的所有位置都失败了)。regex.escape
仅在分隔符列表中可能有特殊的正则表达式字符时使用,例如^
,或。\
-
]
在Python 3.7 中,re.split
也可以使用零长度匹配进行拆分,因此,以下内容也可以:
re.split(r'(?<=[{}])(?!$)'.format(re.escape(delimiters)), s)
否则,您可以使用解决方法,例如
re.findall(r'[^ABS]*[ABS]?', s) # May result in empty items, too
re.findall(r'(?s)(?=.)[^ABS]*[ABS]?', s) # no empty items due to the lookahead requiring at least 1 char
请参阅正则表达式演示。
细节
(?s)
-.
也匹配换行符(?=.)
- 一个字符应立即出现在当前位置的右侧[^ABS]*
A
- 除,B
和之外的任何 0+ 个字符S
[ABS]?
- 1 或 0(=可选)A
,B
或S
字符。改为使用re.findall
,并匹配后跟A
、B
或的数字S
:
re.findall(r'\d+[ABS]', '11A4B')
输出:
['11A', '4B']
如果输入可能还有其他字母字符,则使用否定字符集:
re.findall(r'[^ABS]+[ABS]', 'ZZZAYYYSXXXB')
输出:
['ZZZA', 'YYYS', 'XXXB']
使用findall
:
re.findall('(.*?(?:[ABS]|.$))', "11A4B5")