基于Python的语料库数据处理(七)
《Python玩转语料库数据》专栏·第7篇
文 | 段洵
2826字 | 10 分钟阅读
【数据科学与人工智能】已开通Python语言社群,学用Python,玩弄数据,求解问题,以创价值。喜乐入群者,请加微信号shushengya360,或扫描文末二维码,添加为好友,同时附上Python-入群。有朋自远方来,不亦乐乎,并诚邀入群,以达相互学习和进步之美好心愿。
一、分组
有时候我们不需要返回全部检索内容,而需要对检索的内容分几个部分回,这时候就需要用到分组(grouping)。我们可以将需要分开检索返回的部分用圆括弧括起来。比如,我们需要检索出'http:/www.hust.edu.cn.'网址,并分开返回网址的'http'、'www'、'hust'、'edu'、'cn'等部分,就需要用到分组。请看下面的代码。
import re
web = r'The website of HUST is http://www.hust.edu.cn.'
matched1 = re.findall(r'(http)://(www).(\w+).(\w+).(\w+)', web)
print(matched1) # [('http', 'www', 'hust', 'edu', 'cn')]
print(matched1[0][0]) # http
print(matched1[0][1]) # www
matched2 = re.search(r'(http)://(www).(\w+).(\w+).(\w+)', web)
print(matched2.group(0)) # http://www.hust.edu.cn
print(matched2.group(1)) # http
print(matched2.group(2)) # www
print(matched2.group(3)) # hust
print(matched2.group(4)) # edu
print(matched2.group(5)) # cn
从上述代码可见, re.findall()函数返回一个列表,该列表只有一个元组元素。而元组由五个元素组成,分别是五个圆括弧分组检索到的内容。如果需要访问列表内容,则可以使用pint(matched1[0][0])等来访问。
与re.findall()函数返回列表不同, re.search()返回的内容不能直接访问,而需要通过 group()函数来访问。group(0)返回的内容是表达式检索到的所有内容,所以上述代码中,matched2.group(0)返回的是'http://www.hust.edu.cn'group(1)返回的是第一个分组内容,所以 group(1)返回的是'http'; group(2)返回的是第二个分组内容,所以 group(2)返回的是'www';余类推。
二、元字符的转义
前面我们讲到,正则表达式中有些元字符表示特殊的含义,如“.”可以匹配所有字母、数字、空白和除换行符以外的任意符号;“\”加在一些特殊字母前有特殊含义,如“\w”表示匹配字母或数字或下划线;“?”表示零个或一个等。那么,如何搜索匹配这些元字符呢?这里就需要使用元字符的转义(to escape the metacharacters))。元字符的转义就是在元字符前面加上“\”(反斜线,backslash),以匹配这些元字符。元字符的转义见下表。
假设有下面的文本。
The homepage of our department is http://sfl.hust.edu.cn/. His email address is jason.lee@hotmail.com.
Name: Jason Birthday: 08-12-1988 |
试编写代码完成下面的检索任务:①如何匹配上述文本中的网址?②如何匹配上述文本中的电子邮件地址?③如何匹配上述文本中的生日信息?请看下面的代码。
import re
string = '''The homepage of our department is http://fld.hust.edu.cn/.
His email address is jason.lee@hotmail.com.
Name: Jason
Birthday: 08-12-1988
'''
print(re.findall(r'http://.*?/', string)) # ['http://fld.hust.edu.cn/']
print(re.findall(r'\w+\.\w+@\w+\.\w+', string)) # ['jason.lee@hotmail.com']
print(re.findall(r'\d{2}\-\d{2}\-\d{4}', string)) # ['08-12-1988']
假设有下面的文本。文本中每个单词后面有斜线(/),斜线(1)后面是单词的词性。试编写代码完成下面的检索任务:①如何匹配上述词性赋码文本中的所有专有名词?②如何匹配上述词性赋码文本中的所有名词?③如何匹配上述词性赋码文本中的所有动词?④如何匹配上述词性赋码文本中的“冠词+名词”词组?⑤如何匹配上述词性赋码文本中的最邻近的副词+动词?⑥如何匹配上述词性赋码文本中的所有词性赋码?
The/at marriage/nn of /in John/np and/cc Marry/np Black/np had/hvd clearly/rb reached/vbn the/at breaking/vbg point/nn after/in eight/cd years/nns ./. |
①仔细阅读文本后,我们发现,所有专有名词的词性代码均为/np,所以,检索的表达式为r'\w+np'。②所有名词的词性代码均含有/n,所以,检索的表达式为r'\w+/n\w+'。③与名词类似,所有动词的词性代码均含有/v,所以,检索的表达式为r'\w+/v\w+'。④冠词的词性代码为/at,由于冠词与名词中间可能还有其他单词,故冠词与名词的检索中间加上.*?。.*?表示任意字符的组合,但检索的内容是“懒惰的”。所以,“冠词+名词”词组的检索代码为r'\w+/at.*?\w+/nn\w*'。⑤副词的词性代码含有/rb,所以,最邻近的副词+动词的检索代码为'\w+/rb.*?\w+/v\w*'。⑥检索所有词性赋码,也就是检索所有斜线(/)后面的内容。词性代码可能是几个字母的组合(\w+),或者是句点(\.),所以检索代码为r'∧w+|∧'。
请看下面的示范代码。
import re
string = '''The/at marriage/nn of/in John/np and/cc Mary/np Black/np had/hvd clearly/rb reached/vbn the/at breaking/vbg point/nn after/in eight/cd years/nns ./.
'''
print(re.findall(r'\w+/np', string)) # ['John/np', 'Mary/np', 'Black/np']
print(re.findall(r'\w+/n\w+', string)) # ['marriage/nn', 'John/np', 'Mary/np', 'Black/np', 'point/nn', 'years/nns']
print(re.findall(r'\w+/v\w+', string)) # ['reached/vbn', 'breaking/vbg']
print(re.findall(r'\w+/at.*?\w+/nn\w*', string)) # ['The/at marriage/nn', 'the/at breaking/vbg point/nn']
print(re.findall(r'\w+/rb.*?\w+/v\w*', string)) # ['clearly/rb reached/vbn']
print(re.findall(r'/\w+|/\.', string)) # ['/at', '/nn', '/in', '/np', '/cc', '/np', '/np', '/hvd', '/rb', '/vbn', '/at', '/vbg', '/nn', '/in', '/cd', '/nns', '/.']
# '|' represents 'or'. The above expression can also be written as '(/\w+)|(/\.)'
三、换行符、回车符、制表符
文本中有些字符是肉眼不可见的,比如文本每一段的末尾都有我们看不到的换行符或回车符。正则表达式中用“\n”或“\n\r”表示换行符或回车符。不同的操作系统使用不同的换行符或回车符,如在Mac OS系统和Linux系统中,每行结尾用“\n”表示换行符或回车符;而在微软Windows系统中,每行结尾用“\n\r”表示换行符或回车符。如果需要搜索换行符或回车符,我们可以尝试使用”\n”或“\n\r”来搜索。另外,我们可以用“\t”来搜索制表符。下表列举了换行符、回车符、制表符的转义。
符号 | 注释 |
\n | 匹配换行符(newline,linefeed) |
\r | 匹配回车符(carriage return) |
\t | 匹配制表符(tab) |
推荐阅读:
公众号推荐
数据思践
数据思践公众号记录和分享数据人思考和践行的内容与故事。
Python语言群
诚邀您加入
请扫下方二维码加我为好友,备注Python-入群。有朋自远方来,不亦乐乎,并诚邀入群,以达相互学习和进步之美好心愿。