我正在编写一个python MapReduce字数统计程序。问题是数据中散布着许多非字母字符,我发现这篇文章Stripping everything but alphanumeric chars from a string in Python显示了使用正则表达式的一个很好的解决方案,但我不确定如何实现它
def mapfn(k, v):
print v
import re, string
pattern = re.compile('[\W_]+')
v = pattern.match(v)
print v
for w in v.split():
yield w, 1
我担心我不确定如何使用库re
甚至正则表达式。我不确定如何正确地将正则表达式模式应用于传入的字符串(书的行)v
,以检索没有任何非字母数字字符的新行。
建议?
答案 0 :(得分:78)
使用re.sub
import re
regex = re.compile('[^a-zA-Z]')
#First parameter is the replacement, second parameter is your input string
regex.sub('', 'ab3d*E')
#Out: 'abdE'
或者,如果您只想删除某组字符(因为撇号在您的输入中可能没问题......)
regex = re.compile('[,\.!?]') #etc.
答案 1 :(得分:32)
如果您不想使用正则表达式,可以尝试
''.join([i for i in s if i.isalpha()])
答案 2 :(得分:21)
您可以使用re.sub()函数删除这些字符:
>>> import re
>>> re.sub("[^a-zA-Z]+", "", "ABC12abc345def")
'ABCabcdef'
re.sub(匹配模式,替换字符串,搜索字符串)
"[^a-zA-Z]+"
- 查找任何非字符组
A-ZA-Z。""
- 将匹配的字符替换为"" 答案 3 :(得分:14)
尝试:
s = filter(str.isalnum, s)
答案 4 :(得分:2)
最快的方法是正则表达式
#Try with regex first
t0 = timeit.timeit("""
s = r2.sub('', st)
""", setup = """
import re
r2 = re.compile(r'[^a-zA-Z0-9]', re.MULTILINE)
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)
#Try with join method on filter
t0 = timeit.timeit("""
s = ''.join(filter(str.isalnum, st))
""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""",
number = 1000000)
print(t0)
#Try with only join
t0 = timeit.timeit("""
s = ''.join(c for c in st if c.isalnum())
""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)
2.6002226710006653 Method 1 Regex
5.739747313000407 Method 2 Filter + Join
6.540099570000166 Method 3 Join
答案 5 :(得分:0)
如果计划匹配特定的Unicode属性类,建议使用PyPi regex
module。该库还被证明更稳定,尤其是处理大文本时,并且在各种Python版本中都能产生一致的结果。您需要做的就是保持它为最新。
如果安装(使用pip intall regex
或pip3 install regex
),则可以使用
import regex
print ( regex.sub(r'\P{L}+', '', 'ABCŁąć1-2!Абв3§4“5def”') )
// => ABCŁąćАбвdef
从text
中除去Unicode字母以外的所有1个或多个字符的块。参见online Python demo。您也可以使用"".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”'))
获得相同的结果。
在Python re
中,为了匹配任何Unicode字母,可以使用[^\W\d_]
构造(Match any unicode letter?)。
因此,要删除所有非字母字符,您可以匹配所有字母并加入结果:
result = "".join(re.findall(r'[^\W\d_]', text))
或者,除去与[^\W\d_]
匹配的字符以外的所有字符:
result = re.sub(r'([^\W\d_])|.', r'\1', text, re.DOTALL)
请参见regex demo online。 但是,由于Unicode标准不断发展,并且与\w
匹配的字符集将取决于Python版本,因此在各种Python版本中可能会得到不一致的结果。强烈建议使用PyPi regex
库来获得一致的结果。