我目前有以下代码
def removeControlCharacters(line):
i = 0
for c in line:
if (c < chr(32)):
line = line[:i - 1] + line[i+1:]
i += 1
return line
如果要删除的字符超过一个,这种方法就不起作用了。
我目前有以下代码
def removeControlCharacters(line):
i = 0
for c in line:
if (c < chr(32)):
line = line[:i - 1] + line[i+1:]
i += 1
return line
如果要删除的字符超过一个,这种方法就不起作用了。
Unicode中有数百个控制字符。如果您正在清理来自Web或其他可能包含非ASCII字符的来源的数据,则需要使用Python的unicodedata模块。 unicodedata.category(…)
函数返回任何字符的unicode类别代码(例如,控制字符、空格、字母等)。对于控制字符,类别始终以“C”开头。
此代码段从字符串中删除所有控制字符。
import unicodedata
def remove_control_characters(s):
return "".join(ch for ch in s if unicodedata.category(ch)[0]!="C")
Unicode类别的示例:
>>> from unicodedata import category
>>> category('\r') # carriage return --> Cc : control character
'Cc'
>>> category('\0') # null character ---> Cc : control character
'Cc'
>>> category('\t') # tab --------------> Cc : control character
'Cc'
>>> category(' ') # space ------------> Zs : separator, space
'Zs'
>>> category(u'\u200A') # hair space -------> Zs : separator, space
'Zs'
>>> category(u'\u200b') # zero width space -> Cf : control character, formatting
'Cf'
>>> category('A') # letter "A" -------> Lu : letter, uppercase
'Lu'
>>> category(u'\u4e21') # 両 ---------------> Lo : letter, other
'Lo'
>>> category(',') # comma -----------> Po : punctuation
'Po'
>>>
str.translate
函数,并提供适当的映射关系,例如像这样:>>> mpa = dict.fromkeys(range(32))
>>> 'abc\02de'.translate(mpa)
'abcde'
map
用作变量名称。 - Mark ByersTypeError: expected a character buffer object
错误提示。Python 版本是 2.6。 - user1476056python-3.x
。 - SilentGhostdict.fromkeys(range(33))
,因为 range
是上限排除的。 - dustinfarris有兴趣匹配任何Unicode 控制字符 的正则表达式字符类,可以使用[\x00-\x1f\x7f-\x9f]
。
您可以像这样测试:
>>> import unicodedata, re, sys
>>> all_chars = [chr(i) for i in range(sys.maxunicode)]
>>> control_chars = ''.join(c for c in all_chars if unicodedata.category(c) == 'Cc')
>>> expanded_class = ''.join(c for c in all_chars if re.match(r'[\x00-\x1f\x7f-\x9f]', c))
>>> control_chars == expanded_class
True
因此,要使用re
删除控制字符,请使用以下代码:
>>> re.sub(r'[\x00-\x1f\x7f-\x9f]', '', 'abc\02de')
'abcde'
Cc
,而那个适用于 C*
。 - hyperknot这是我所知道的最简单、最完整、最强大的方法。但是它需要一个外部依赖项,对于大多数项目来说,我认为这是值得的。
pip install regex
import regex as rx
def remove_control_characters(str):
return rx.sub(r'\p{C}', '', 'my-string')
\p{C}
是Unicode字符属性,用于控制字符,所以你可以让Unicode负责决定哪些数百万可用的Unicode字符应被视为控制字符。还有其他非常有用的字符属性,例如\p{Z}
表示任何类型的空格。
regex
库将具有最新的Unicode信息。 - scribumy_dataframe['column_1'].str
是您的输入字符串,您可以使用 rx.sub(r'\p{C}', '', my_dataframe['column_1'].str)
返回已清理的字符串。 - cmc您的实现存在问题,因为i
的值不正确。但这并不是唯一的问题:它还反复使用缓慢的字符串操作,这意味着它的运行时间是O(n2)而不是O(n)。请尝试使用以下代码:
return ''.join(c for c in line if ord(c) >= 32)
str.translate
и‡іе°‘ж…ўдє†дё¤еЂЌгЂ‚ - SilentGhostord()
在非BMP字符上是否会出错?对我来说[ord(c) for c in u'\U00020000']
运行正常,结果列表中的值都>=32,因为它们是代理对。 - Ben Hoytord(u'\U00020000')
在 Python 的 UCS2 版本中会失败,但在这种情况下使用 ord(c)
是可以的,因为迭代字符串总是会得到小于等于 65535 的字符。 - Ben Hoyt对于Python 2,使用内置的translate
函数:
import string
all_bytes = string.maketrans('', '') # String of 256 characters with (byte) value 0 to 255
line.translate(all_bytes, all_bytes[:32]) # All bytes < 32 are deleted (the second argument lists the bytes to delete)
''.join([x for x in line if ord(x) >= 32])
的代码。filter(string.printable[:-5].__contains__,line)
我尝试了上述所有方法,但都没有帮助。在我的情况下,我不得不删除Unicode的“LRM”字符:
最终,我找到了这个解决方案,它解决了我的问题:
df["AMOUNT"] = df["AMOUNT"].str.encode("ascii", "ignore")
df["AMOUNT"] = df["AMOUNT"].str.decode('UTF-8')
参考这里。
Cn
类别中的字符,这些字符只是“未分配”的字符(目前可用Unicode点的约75%)。通常,您也不希望在字符串中包含这些字符,但在某些情况下区别很重要。 - Indigenuity