我有一个包含一些我需要保留的替换的列表。例如,替换列表:['1st', '2nd', '10th', '100th', '1st nation', 'xlr8', '5pin', 'h20']
。
一般来说,包含字母数字字符的字符串需要按如下方式分割数字和字母:
text = re.sub(r'(?<=\d)(?=[^\d\s])|(?<=[^\d\s])(?=\d)', ' ', text, 0, re.IGNORECASE)
以前的正则表达式模式通过在以下内容之间添加空格成功地将所有数字与字符分开:
Original Regex
ABC10 DEF --> ABC 10 DEF
ABC DEF10 --> ABC DEF 10
ABC 10DEF --> ABC 10 DEF
10ABC DEF --> 10 ABC DEF
但是,有一些字母数字单词是替换列表的一部分,无法分开。例如,以下包含 1ST
的字符串(属于替换列表的一部分)不应被分隔,而应被省略,而不是添加空格:
Original Regex Expected
1ST DEF 100CD --> 1 ST DEF 100 CD --> 1ST DEF 100 CD
ABC 1ST 100CD --> ABC 1 ST 100 CD --> ABC 1ST 100 CD
100TH DEF 100CD -> 100 TH DEF 100 CD -> 100TH DEF 100 CD
10TH DEF 100CD -> 10 TH DEF 100 CD -> 10TH DEF 100 CD
为了获得上面示例中的预期列,我尝试在正则表达式中使用 IF THEN ELSE
方法,但在 Python 语法中出现错误:
(?(?=condition)(then1|then2|then3)|(else1|else2|else3))
根据语法,我应该有如下内容:
?(?!1ST)((?<=\d)(?=[^\d\s])|(?<=[^\d\s])(?=\d)))
其中 (?!...)
将包括匹配正则表达式模式时要避免的可能替换,在本例中为单词 1ST 10TH 100TH
。
如何避免字符串中匹配的单词替换?
最佳答案
您可以使用 lambda 函数来检查匹配的字符串是否在排除列表中:
import re
subs = ['1st','2nd','1st nation','xlr8','5pin','h20']
text = """
ABC10 DEF
1ST DEF 100CD
ABC 1ST 100CD
AN XLR8 45X
NO H20 DEF
A4B PLUS
"""
def add_spaces(m):
if m.group().lower() in subs:
return m.group()
res = m.group(1)
if len(res):
res += ' '
res += m.group(2)
if len(m.group(3)):
res += ' '
res += m.group(3)
return res
text = re.sub(r'\b([^\d\s]*)(\d+)([^\d\s]*)\b', lambda m: add_spaces(m), text)
print(text)
输出:
ABC 10 DEF
1ST DEF 100 CD
ABC 1ST 100 CD
AN XLR8 45 X
NO H20 DEF
A 4 B PLUS
您可以将 lambda 函数简化为
def add_spaces(m):
if m.group().lower() in subs:
return m.group()
return m.group(1) + ' ' + m.group(2) + ' ' + m.group(3)
但这可能会导致输出字符串中出现额外的空格。然后可以使用
删除它text = re.sub(r' +', ' ', text)
关于python - Python 中的正则表达式 : Separate words from numbers JUST when not in list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59743531/