【发布时间】:2011-09-13 11:26:57
【问题描述】:
我在使用 Python 正则表达式时遇到了一点问题。
有什么好的方法可以删除字符串中不是字母或数字的所有字符?
谢谢!
【问题讨论】:
-
有问题的字符串不包含 ascii 字符?
我在使用 Python 正则表达式时遇到了一点问题。
有什么好的方法可以删除字符串中不是字母或数字的所有字符?
谢谢!
【问题讨论】:
您还可以考虑其他方式,例如只需循环遍历字符串并跳过不需要的字符,例如假设您要删除所有非字母或数字的 ascii 字符
>>> newstring = [c for c in "a!1#b$2c%3\t\nx" if c in string.letters + string.digits]
>>> "".join(newstring)
'a1b2c3x'
或使用 string.translate 将一个字符映射到另一个字符或删除一些字符,例如
>>> todelete = [ chr(i) for i in range(256) if chr(i) not in string.letters + string.digits ]
>>> todelete = "".join(todelete)
>>> "a!1#b$2c%3\t\nx".translate(None, todelete)
'a1b2c3x'
这样你需要计算一次todelete列表或todelete可以硬编码一次,并在你需要转换字符串的任何地方使用它
【讨论】:
[\w] 匹配(字母数字或下划线)。
[\W] 匹配 (not (alphanumeric or underscore)),相当于 (not alphanumeric and not underscore)
您需要[\W_] 删除所有非字母数字。
使用 re.sub() 时,如果通过使用 [\W_]+ 匹配而不是一次一个匹配来减少替换的数量(昂贵),效率会高得多。
现在您只需定义字母数字:
str 对象,仅 ASCII A-Za-z0-9:
re.sub(r'[\W_]+', '', s)
str 对象,仅限语言环境定义的字母数字:
re.sub(r'[\W_]+', '', s, flags=re.LOCALE)
unicode 对象,所有字母数字:
re.sub(ur'[\W_]+', u'', s, flags=re.UNICODE)
str 对象的示例:
>>> import re, locale
>>> sall = ''.join(chr(i) for i in xrange(256))
>>> len(sall)
256
>>> re.sub('[\W_]+', '', sall)
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
>>> re.sub('[\W_]+', '', sall, flags=re.LOCALE)
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
>>> locale.setlocale(locale.LC_ALL, '')
'English_Australia.1252'
>>> re.sub('[\W_]+', '', sall, flags=re.LOCALE)
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\x83\x8a\x8c\x8e\
x9a\x9c\x9e\x9f\xaa\xb2\xb3\xb5\xb9\xba\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\
xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\
xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\
xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
# above output wrapped at column 80
Unicode 示例:
>>> re.sub(ur'[\W_]+', u'', u'a_b A_Z \x80\xFF \u0404', flags=re.UNICODE)
u'abAZ\xff\u0404'
【讨论】:
'\W' 与 [^A-Za-z0-9_] 相同,加上您所在地区的重音字符。
>>> re.sub('\W', '', 'text 1, 2, 3...')
'text123'
也许您想保留空格或保留所有单词(和数字):
>>> re.findall('\w+', 'my. text, --without-- (punctuation) 123')
['my', 'text', 'without', 'punctuation', '123']
【讨论】:
_。 \w == [^a-zA-Z0-9_]
你需要更具体:
A-Z 和 a-z?0-9吗?小数、分隔符和指数呢?它很快变得复杂......
一个很好的起点是交互式正则表达式网站,例如RegExr
您还可以获取 Python 特定的Python Regex Tool
【讨论】:
您也可以尝试通过以下方式使用 isalpha 和 isnumeric 方法:
text = 'base, sample test;'
getVals = lambda x: (c for c in text if c.isalpha() or c.isnumeric())
map(lambda word: ' '.join(getVals(word)): text.split(' '))
【讨论】:
isalnum() 方法!尽管 OP 确实要求使用正则表达式
您可以在 python 中使用预定义的正则表达式:\W 对应于集合[^a-zA-Z0-9_]。那么,
import re
s = 'Hello dutrow 123'
re.sub('\W', '', s)
--> 'Hellodutrow123'
【讨论】:
在字符集匹配规则[...] 中,您可以将^ 指定为第一个字符以表示“不在”
import re
re.sub("[^0-9a-zA-Z]", # Anything except 0..9, a..z and A..Z
"", # replaced with nothing
"this is a test!!") # in this string
--> 'thisisatest'
【讨论】: