Python 文本字符串清理

文本字符串清理


由于收集来源的问题(比如,表单文本数据录入错误,甚至于有意录入错误的数据),文本字符串往往需要先进行清理才能够在后续的需求中发挥正常且正确的作用。

删除字符串中多余的字符^{[1]}


在文本字符串中,经常会遇到开头,结尾或者中间不需要的字符,例如空白符。

strip()、lstrip()、rstrip()

strip() 方法用于移除开始或结尾的字符。该方法接受一个参数 chars,该参数为指定要移除的字符。若缺省或为 None,默认指定移除空白符。

lstrip()rstrip() 方法参数同 strip()lstrip() 从左执行移除操作,而 rstrip() 从右执行移除操作。

举例说明三者的用法及效果:

>>> # 空白符的移除
... s = ' hello world \n'
>>> s.strip()  # 移除前后空白符
'hello world'
>>> s.lstrip()  # 移除前空白符
'hello world \n'
>>> s.rstrip()  # 移除后空白符
' hello world'
>>>
>>> # 指定其他字符的移除
... s = 'www.example.com'
>>> s.strip('cmowz.')
'example'
>>> s.lstrip('cmowz.')
'example.com'
>>> s.rstrip('cmowz.')
'www.example'

对于上述代码,移除空白字符比较好理解。指定移除其他字符,实际上执行的过程:移除的过程中遇到一个字符未包含于 chars 所指定的字符集中时,将停止操作。(如 lstrip() 示例中遇到 e 字符并未包含于指定字符集 cmowz. 中,此时执行停止,返回剩余部分的内容。)

在处理数据以备后续使用,这些 strip() 方法往往会被频繁调用。但是,这里需要注意的是,这些方法并不能够对字符串中间的文本产生任何影响。如下示例:

>>> s = ' hello      world \n'
>>> s.strip()
'hello      world'

如果需要移除中间的空格,可以考虑使用 replace() 方法或者是用正则表达式中的 sub 进行替换。示例如下:

>>> s = 'hello      world'
>>> s.replace(' ','')
'helloworld'
>>> import re
>>> re.sub('\s+', ' ', s)
'hello world'

清洗文本字符串


有些用户,会恶作剧在网站页面表单输入 Unicode 文本,例如 Un̄ićŏdè ,现在的需求是将这些字符进行清理。

文本清理会涉及文本解析和数据处理等系列问题。较为简单的情形下,可以选择将文本转为标准格式(例如:str.upper()str.lower()),然后利用替换操作(比如:str.replace() 或者 re.sub()),删除或者替换指定字符。

str.translate()^{[2]}

str.translate(table) 主要的作用是返回原字符串的副本,其中每个字符按给定的转换表进行映射。参数 table 必须是使用 __getitem__() 实现索引操作的对象,通常为 mappingsequence。如下示例:

>>> s = 'Un̄ićŏdè, the\fworld standard\tfor text and emoji\r\n'
>>> given_map = {
...     ord('\t'): ' ',
...     ord('\f'): ' ',
...     ord('\r'): None
... }
>>> a = s.translate(given_map)
>>> a
'Un̄ićŏdè, the world standard for text and emoji\n'

返回的结果中,空白字符 \t\f 被重新映射为一个空格。而返回 None 这部分,表示删除字符 \r

unicodedata 模块


unicodedata.normalize()^{[3]}

上面提及的 Un̄ićŏdè,这种带有和音符的字符串。可以使用尝试使用 str.translate() 方法构建更完整的转换表,用来删除和音符。如下示例:

>>> import sys
>>> import unicodedata
>>> a = 'Un̄ićŏdè, the world standard for text and emoji\n'
>>> cmb_chrs = dict.fromkeys(c for c in range(sys.maxunicode) if unicodedata.combining(chr(c)))
>>> b = unicodedata.normalize('NFD', a)
>>> b
'Un̄ićŏdè, the world standard for text and emoji\n'
>>> b.translate(cmb_chrs)
'Unicode, the world standard for text and emoji\n'
>>>

dict.fromkeys(seq[, value]) 方法,返回一个新字典,value 默认为 None。在这个例子中,dict.fromkeys() 方法用于构造一个字典,每个 Unicode 和音符作为键,对应的值全部为 None

unicodedata.normalize(form, unistr) 返回 Unicode 字符串 unistr 的正常形式 form。 form 的有效值为 NFCNFKCNFDNFKDcombining() 方法用于确认字符是否为和音符。示例中的 Unicode 文本是由字母与和音符组合而成的,使用 NFD 将字符转换为分解形式,然后用 translate 函数删除所有的和音符。

encode() 和 decode()

还有另外一种方法,涉及到 I/O 解码与编码函数。如下示例:

>>> a
'Un̄ićŏdè, the world standard for text and emoji\n'
>>> b = unicodedata.normalize('NFD', a)
>>> b.encode('ascii', 'ignore').decode('ascii')
'Unicode, the world standard for text and emoji\n'

代码的执行流程:同样是先用 normalize() 方法先分解和音符。然后在 ASCII 编码/解码的过程中丢弃掉这些字符。这种方法只有在获取文本到对应 ASCII 的时候才会生效。

关于性能方面的问题,简单替换操作,str.replace() 体现的优势更明显。但,如果需要清理复杂字符,对字符重新映射或删除,translate() 的表现更好。具体使用哪种方法,要多方面尝试评估再采用。

参考资料

来源

[1] David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O'Reilly Media.2013.
[2] "4. Built-in Types — Python 3.6.10 documentation".python.org. Retrieved 13 November 2019.
[3] "6.5. unicodedata — Unicode Database".Docs.python.org. Retrieved 3 January 2020.


以上就是本篇的主要内容


\bf{欢迎关注『书所集录』公众号}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容