我们在做文本预处理工作时,经常需要使用正则表达式。例如:判断是否是中文、是否是标点符号、是否是空行等等,我们将这些常用的用法记录下来,方便下次使用。
# 匹配单个字符 . 匹配任意1个字符(除了\n) [ ] 匹配[ ]中列举的字符 \d 匹配数字,即0-9 \D 匹配非数字,即不是数字 \s 匹配空白,即 空格,tab键 \S 匹配非空白 \w 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字 \W 匹配特殊字符,即非字母、非数字、非汉字 # 匹配多个字符 * 匹配前一个字符出现0次或者无限次 + 匹配前一个字符出现1次或者无限次 ? 匹配前一个字符出现1次或者0次 {m} 匹配前一个字符出现m次 {m,n} 匹配前一个字符出现从m到n次 # 开头和结束 ^ 匹配开头字符 $ 匹配结束字符 # 其他 | 匹配左右任意一个表达式 (ab) 将括号中字符作为一个分组 \num 引用分组num匹配到的字符串 (?P<name>) 分组起别名 (?P=name) 引用别名为name分组匹配到的字符串
1. 判断是否中文
import re def test(): text = re.sub(r'[\u4e00-\u9fa5]', ' ', '我a是b中c国d人') print(text) if __name__ == '__main__': test()
程序输出结果:
a b c d
2. 连续空格处理
import re def test(): text = re.sub(r'[ ]+', '', ' 我 是 中 国 人 ') print(text) if __name__ == '__main__': test()
程序输出结果:
我是中国人
3. 英文简写还原
import re def test(): pattern = {r"(w|W)on't" : r"\1ill not", r"(c|C)an't" : r"\1an not", r"(a|A)in't" : r"is not", r"(i|I)'m" : r"\1 am", r"(\w+)'ve" : r"\1 have", r"(\w+)'re" : r"\1 are", r"(\w+)'ll" : r"\1 will", r"(\w+)'d" : r"\1 would", r"(\w+)'s" : r"\1 is", r"(\w+)n't" : r"\1 not"} texts = ["We won't talk about that ─ that's history.", "Can't you control your children?", "Things ain't what they used to be.", "I'm a big fan of hers.", "I'd like one the same as yours.", "They're very good employers.", "I stayed hidden; I couldn't chance coming out.", "He's one of my best friends."] for text in texts: for key, value in pattern.items(): text = re.sub(key, value, text) print(text) if __name__ == '__main__': test()
程序输出结果:
We will not talk about that ─ that is history. Can not you control your children? Things is not what they used to be. I am a big fan of hers. I would like one the same as yours. They are very good employers. I stayed hidden; I could not chance coming out. He is one of my best friends.
4. 简体繁体转换
# pip install zhconv # zh-cn 大陆简体 # zh-tw 台灣正體 # zh-hk 香港繁體 # zh-sg 马新简体(无词汇表,需要手工指定) # zh-hans 简体 # zh-hant 繁體 import zhconv if __name__ == '__main__': # 繁体转换简体 content = zhconv.convert('我是中國人', 'zh-cn') print(content) # 简体转繁体 content = zhconv.convert('我是中国人', 'zh-hant') print(content)
输出结果:
我是中国人 我是中國人
5. 中文标点符号转换
def convert(ch): # 定义英文标点符号到中文标点符号的映射字典 punctuation = { '.': '。', ',': ',', '!': '!', '?': '?', ':': ':', ';': ';', "'": '‘', '"': '“', '(': '(', ')': ')', '[': '【', ']': '】', '{': '{', '}': '}', '-': '-', '_': '_', '&': '&', '@': '@', '#': '#', '$': '$', '%': '%', '+': '+', '=': '=', '<': '<', '>': '>', '/': '/', '\\': '\', '|': '|' # 添加更多的映射,如果需要的话 } if ch not in punctuation: return ch return punctuation[ch]
6. 文本标准化
pip install pyhanlp if __name__ == '__main__': # load_data() normalizer = JClass('com.hankcs.hanlp.dictionary.other.CharTable') text = normalizer.convert('2012年9月5日,中央电视台《艺术人生》节目主持人朱军先生在首都北京亲切会见了中国著名书法家高咏华先生') print(text)
程序输出结果:
2012年9月5日,中央电视台《艺术人生》节目主持人朱军先生在首都北京亲切会见了中国著名书法家高咏华先生
7. 去除标点符号
# pip install zhon import zhon.hanzi as zh import string as en def remove_punctuation(sentence): punctuation = zh.punctuation + en.punctuation word_list = [] for word in sentence: if word not in punctuation: word_list.append(word) return ''.join(word_list) if __name__ == '__main__': print(remove_punctuation('《水浒传》是元末明初施耐庵(现存刊本署名大多有施耐庵、罗贯中两人中的一人,或两人皆有)编著的章回体长篇小说。'))
程序输出结果:
水浒传是元末明初施耐庵现存刊本署名大多有施耐庵罗贯中两人中的一人或两人皆有编著的章回体长篇小说
8. 最长最短文本
最短行文本:awk ‘(NR==1||length(min)>length()){min=$0}END{print min}’ inputs.txt 最长行文本:awk ‘{if (length(max)<length()) max=$0}END{print max}’ inputs.txt