请考虑下表的第一栏中显示的以下原始字符串:
Original String Parsed String Desired String
'W. & J. JOHNSON LMT.COM' #W J JOHNSON LIMITED #WJ JOHNSON LIMITED
'NORTH ROOF & WORKS CO. LTD.' #NORTH ROOF WORKS CO LTD #NORTH ROOF WORKS CO LTD
'DAVID DOE & CO., LIMITED' #DAVID DOE CO LIMITED #DAVID DOE CO LIMITED
'GEORGE TV & APPLIANCE LTD.' #GEORGE TV APPLIANCE LTD #GEORGE TV APPLIANCE LTD
'LOVE BROS. & OTHERS LTD.' #LOVE BROS OTHERS LTD #LOVE BROS OTHERS LTD
'A. B. & MICHAEL CLEAN CO. LTD.'#A B MICHAEL CLEAN CO LTD #AB MICHAEL CLEAN CO LTD
'C.M. & B.B. CLEANER INC.' #C M B B CLEANER INC #CMBB CLEANER INC
我已按如下所示删除标点符号:
def transform(word):
word = re.sub(r'(?<=[A-Za-z])\'(?=[A-Za-z])[A-Z]|[^\w\s]|(.com|COM)',' ',word)
但是,我没有最后一点。删除标点符号后,我最终得到了很多空格。我如何拥有一个将首字母放在一起并保留单个空格的正则表达式(没有首字母)的正则表达式?
替换提到的字符以获得所需的字符串是一种不好的方法吗?
感谢您允许我继续学习:)
我认为部分执行此操作比较简单。首先,删除.com
和space
或&
以外的其他标点符号。然后,删除仅用一个字母包围的space
或&
。最后,用单个空格替换space
或&
的所有剩余序列:
import re
strings = ['W. & J. JOHNSON LMT.COM',
'NORTH ROOF & WORKS CO. LTD.',
'DAVID DOE & CO., LIMITED',
'GEORGE TV & APPLIANCE LTD.',
'LOVE BROS. & OTHERS LTD.',
'A. B. & MICHAEL CLEAN CO. LTD.',
'C.M. & B.B. CLEANER INC.'
]
for s in strings:
s = re.sub(r'\.COM|[^a-zA-Z& ]+', '', s, 0, re.IGNORECASE)
s = re.sub(r'(?<=\b\w)\s*[ &]\s*(?=\w\b)', '', s)
s = re.sub(r'\s*[& ]\s*', ' ', s)
print s
输出
WJ JOHNSON LMT
NORTH ROOF WORKS CO LTD
DAVID DOE CO LIMITED
GEORGE TV APPLIANCE LTD
LOVE BROS OTHERS LTD
AB MICHAEL CLEAN CO LTD
CM BB CLEANER INC
更新
这是在编辑问题之前写的,以更改最后一个数据的所需结果。进行编辑后,以上代码可以简化为
for s in strings:
s = re.sub(r'\.COM|[^a-zA-Z ]+|\s(?=&)|(?<!\w\w)\s+(?!\w\w)', '', s, 0, re.IGNORECASE)
print s
这里是最简单的一种正则表达式模式:
\.COM|(?<![A-Z]{2}) (?![A-Z]{2})|[.&,]| (?>)&
基本上,它删除符合3个条件的字符:
仅在正则表达式中执行此操作就不会很漂亮,也不是最佳解决方案,但是,这确实是!您最好采用多步骤方法。我所做的是确定所有可能的情况,并选择一种解决方案,其中没有替换字符串,因为您并不总是用空格替换字符。
A. B.
或W. & J.
的位置,但不是C.M. & B.B.
A.
)在前后的位置,但后面没有另一个字母字符&
和J.
中的点的位置>'LOVE
的位置(该字符串中的撇号)完成此操作的多合一正则表达式如下:
(?<=\b[a-z])[^a-z]+(?=[a-z]\b(?![^a-z][a-z]))|(?<= ) *(?:\.com\b|[^a-z\s]+) *| *(?:\.com\b|[^a-z\s]+) *(?= )|(?<! )(?:\.com\b|[^a-z\s]+)(?! )
工作原理如下(分解为每个交替):
(?<=\b[a-z])[^a-z]+(?=[a-z]\b(?![^a-z][a-z]))
匹配A.
和B.
之间的非字母字符,但不匹配A.
和B.B
(?<=\b[a-z])
向后保证正向,确保后面是一个字母字符,并在其左边声明单词边界位置[^a-z]+
匹配任何一个非字母字符一次或多次(?=[a-z]\b(?![^a-z][a-z]))
正向前瞻确保存在以下条件[a-z]\b
匹配任何字母字符并在其右边声明单词边界位置(?![^a-z][a-z])
否定前瞻,确保后面不是非字母字符,后跟字母字符(?<= ) *(?:\.com\b|[^a-z\s]+) *
确保前面有一个空格,然后匹配任何空格,.com
或任何非单词非空白字符一次或多次,然后匹配任何空格(?<= )
向后看以确保前面有空格*
匹配任意数量的空格(?:\.com\b|[^a-z\s]+)
匹配.com
并确保后面跟随一个非单词字符,或一次或多次匹配任何一个非单词非空白字符*
匹配任意数量的空格*(?:\.com\b|[^a-z\s]+) *(?= )
匹配任何空格,.com
或任何非单词非空白字符一次或多次,然后匹配任何空格,然后确保后面跟随一个空格(?<! )(?:\.com\b|[^a-z\s]+)(?! )
匹配.com
或任何非alpha-非空白字符一次或多次,以确保没有空格import re strings = [ "'W. & J. JOHNSON LMT.COM'", "'NORTH ROOF & WORKS CO. LTD.'", "'DAVID DOE & CO., LIMITED'", "'GEORGE TV & APPLIANCE LTD.'", "'LOVE BROS. & OTHERS LTD.'", "'A. B. & MICHAEL CLEAN CO. LTD.'", "'C.M. & B.B. CLEANER INC.'" ] r = re.compile(r'(?<=\b[a-z])[^a-z]+(?=[a-z]\b(?![^a-z][a-z]))|(?<= ) *(?:\.com\b|[^a-z\s]+) *| *(?:\.com\b|[^a-z\s]+) *(?= )|(?<! )(?:\.com\b|[^a-z\s]+)(?! )', re.IGNORECASE) def transform(word): return re.sub(r, '', word) for s in strings: print(transform(s))
输出:
WJ JOHNSON LMT NORTH ROOF WORKS CO LTD DAVID DOE CO LIMITED GEORGE TV APPLIANCE LTD LOVE BROS OTHERS LTD AB MICHAEL CLEAN CO LTD CM BB CLEANER INC