正規表現を使用します
正規表現関連の知識
プログラムまたはWebページ処理の文字列を記述する場合は、文字列は正規表現の特定の複雑なルールを満たす見つける必要があることが多いこれらのルールの説明をするためのツールである、言い換えれば、正規表現はツールということですこれは、(一部に一致するか、から抽出された、または文字列がパターンに一致する部分を置き換えるパターンの文字列かどうかを確認する方法)パターン文字列マッチングを定義します。ファイル名(*と?)を指定するときは、Windowsオペレーティングシステムを見つけるために使用されるファイルとワイルドカードを使用した場合、その後の正規表現も同様の一致したテキストとツールのために使用されるが、正規表現のワイルドカードと比較され、スタイルは、より強力な、より正確に、ワイルドカードは、再生するためにあなたの価格のすべての利点をもたらすために何かを知っているよりも、もちろん、あなたが正規表現を書いている支払う価格ははるかに複雑である(あなたのニーズを記述することができます「 - 」プログラミング言語を学ぶことに似て)、例えば、あなたは2-3の数字、そしてハイフン0を持つすべての始まりを見つけるために使用される正規表現を書くことができます最後、7または8 (0813-7654321または028-12345678など)数値文字列は、この国内の固定電話番号してくださいではありません。当初は数学や出産を行うには、コンピュータ、情報の処理は、基本的価値であり、今日の我々は彼らの毎日の仕事に情報を扱っている基本的にテキストデータは、我々はコンピュータがテキストに沿って一定のパターンを認識して処理できるようにしたいされています、正規表現は非常に重要です。今日では、ほとんどすべてのプログラミング言語は、正規表現操作のサポートを提供し、Pythonの標準ライブラリの再モジュールが運営する正規表現をサポートしています。
私たちは、次の質問を検討することができます:我々は、(テキストファイルである可能性があり、ネットワーク上のニュースかもしれない)文字列中の電話番号や固定電話の番号を見つけることを期待して、どこから文字列を取得します。もちろん、私たちは(あなたが見ていないので、ノートではないランダムな11桁の番号「25012345678」この電話番号に)電話番号が11ビットのデジタルで設定していない場合は、固定電話番号について説明したのと同じパターンを維持することができますこのタスクを達成するために正規表現を使用することは非常に面倒になります。
正規表現についての知識は、あなたが呼ばれる非常に有名なブログ読むことができる「正規表現30分ガイド」あなたは正の私たちの表現で、次の表を参照して、読むことができますこの記事を読んだ後、基本的な記号のいくつかの簡単な要約。
シンボル | 説明 | 例 | 説明 |
---|---|---|---|
。 | 任意の文字と一致 | BT | マッチバット/しかし/ Bの#tは/ B1Tなど |
\ワット | マッチ文字/数字/アンダースコア | B \重量 | マッチバット/ B1T /のようなB_T が、Bの#tを一致させることはできません |
\ sの | (など\ rを、\ nは、\ tの、を含む)空白文字を一致させます | \ syou愛 | マッチはあなたを愛して |
\ dは | マッチング番号 | \ D \ dは | マッチ01/23/99など |
\ B | 単語の境界をマッチング | \ bThe \ B | |
^ | 文字列の先頭にマッチします | ^ | 文字列の一致始まり |
$ | 試合終了の文字列 | .exeの$ | あなたは.EXEで終わる文字列を一致させることができます |
\ W | 非マッチング文字/数字/アンダースコア | B \重量 | マッチB番号のT / Bの@ tのように 、それが一致していませんが、/ B1T / B_Tなど |
\ S | 非空白文字をマッチング | \ Syouを愛し | #愛あなたは一致させることができますし、そうで はなく、あなたを愛して一致することはできません |
\ D | 非数値のマッチング | \ D \ D | マッチ部9a / 3#/ 0Fなど |
\ B | 非ワード境界をマッチング | \バイオ\ B | |
[] | 文字セットから任意の1文字に一致します | [AEIOU] | 任意の文字の母音にマッチします |
[^] | 文字セットにない任意の1文字に一致します | [^ AEIOU] | 非母音の文字のいずれかと一致 |
* | マッチ0回以上 | \ワット* | |
+ | マッチ1回以上 | \ワット+ | |
? | マッチ0または1 | \ワット? | |
{N} | マッチN回 | \ {3}のw | |
{M} | マッチ少なくともM回 | \ {3}のw | |
{M、N} | ほとんどのM倍で少なくともN回のマッチング | \ {3,6}のw | |
| | ブランチ | FOO |バー | あなたはFOOやバーを一致させることができます |
(?#) | 注記 | ||
(EXP) | EXPと捕捉自動的に名前付きグループに一致 | ||
(?<名前> EXP) | 経験のグループの試合とで指定された名前をキャプチャ | ||
(?:EXP) | 経験の結果一致したが、試合のテキストをキャプチャしていません | ||
(?= EXP) | EXPの前の位置をマッチング | \ \ + W B(?= INGの) | 私はdancを一致させることができます踊っています |
(?<= EXP) | EXPの後ろに位置をマッチング | (?<= \ bdanc)\ W + \ B | マッチ私が踊ると最初のINGを読んで大好き |
(?!EXP) | 後方の位置と一致しないEXP | ||
(?<!EXP) | EXPの前の位置と一致しません | ||
*? | 何回繰り返して、任意の数が、あまり重複可能な限り | 。* B 。*?B |
正規表現を適用aababは、前者は二つの文字列ABとAABと一致します文字列全体のaababを、一致します |
+? | 1回以上繰り返し、あまり重複可能な限り | ||
?? | 可能な限り0または1を繰り返しますが、あまり重複 | ||
{M、N}? | MにN回繰り返したが、以下のように繰り返されます | ||
{M}? | 繰り返されるM回以上、あまり重複可能な限り |
注:あなたが文字を一致させる必要がある場合は、正規表現の特殊文字である、あなたは\エスケープを使用することができ、例えば、直接書き込みは任意の文字に一致しますので、小数点は、その上の\書き込むことができます一致させたい、同じトークン、と思います。一致括弧は\書き込まなければならない(および\)、またはグループ化括弧は正規表現として扱われます。
正規表現のためのPythonサポート
Pythonは、モジュールが再モジュールはコア関数であり、次の正規表現のサポートに関連する操作を提供再。
機能 | 説明 |
---|---|
コンパイル(パターン、フラグ= 0) | 正規表現をコンパイルすると、正規表現オブジェクトを返します。 |
マッチ(パターン、文字列、フラグ= 0) | 文字列にマッチする正規表現を使用して成功したリターンマッチオブジェクトそうでない場合はなし |
検索(パターン、文字列、フラグ= 0) | オブジェクトに一致する検索文字列の正規表現パターンが最初に出現しそうでない場合は正常な戻りなし |
スプリット(パターン、文字列、maxsplit個= 0、フラグ= 0) | 指定された正規表現パターン文字列は、リストの区切りスプリットを返します。 |
サブ(パターン、REPL、文字列、カウント= 0、フラグ= 0) | 交換指定された文字列と一致する元の文字列と正規表現パターンは、交換カウントの数で指定することができます |
fullmatch(パターン、文字列、フラグ= 0) | match函数的完全匹配(从字符串开头到结尾)版本 |
findall(pattern, string, flags=0) | 查找字符串所有与正则表达式匹配的模式 返回字符串的列表 |
finditer(pattern, string, flags=0) | 查找字符串所有与正则表达式匹配的模式 返回一个迭代器 |
purge() | 清除隐式编译的正则表达式的缓存 |
re.I / re.IGNORECASE | 忽略大小写匹配标记 |
re.M / re.MULTILINE | 多行匹配标记 |
说明: 上面提到的re模块中的这些函数,实际开发中也可以用正则表达式对象的方法替代对这些函数的使用,如果一个正则表达式需要重复的使用,那么先通过compile函数编译正则表达式并创建出正则表达式对象无疑是更为明智的选择。
下面我们通过一系列的例子来告诉大家在Python中如何使用正则表达式。
例子1:验证输入用户名和QQ号是否有效并给出对应的提示信息。
"""
验证输入用户名和QQ号是否有效并给出对应的提示信息
要求:用户名必须由字母、数字或下划线构成且长度在6~20个字符之间,QQ号是5~12的数字且首位不能为0
"""
import re
def main():
username = input('请输入用户名: ')
qq = input('请输入QQ号: ')
# match函数的第一个参数是正则表达式字符串或正则表达式对象
# 第二个参数是要跟正则表达式做匹配的字符串对象
m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username)
if not m1:
print('请输入有效的用户名.')
m2 = re.match(r'^[1-9]\d{4,11}$', qq)
if not m2:
print('请输入有效的QQ号.')
if m1 and m2:
print('你输入的信息是有效的!')
if __name__ == '__main__':
main()
提示: 上面在书写正则表达式时使用了“原始字符串”的写法(在字符串前面加上了r),所谓“原始字符串”就是字符串中的每个字符都是它原始的意义,说得更直接一点就是字符串中没有所谓的转义字符啦。因为正则表达式中有很多元字符和需要进行转义的地方,如果不使用原始字符串就需要将反斜杠写作\\,例如表示数字的\d得书写成\\d,这样不仅写起来不方便,阅读的时候也会很吃力。
例子2:从一段文字中提取出国内手机号码。
下面这张图是截止到2017年底,国内三家运营商推出的手机号段。
import re
def main():
# 创建正则表达式对象 使用了前瞻和回顾来保证手机号前后不应该出现数字
pattern = re.compile(r'(?<=\D)1[34578]\d{9}(?=\D)')
sentence = '''
重要的事情说8130123456789遍,我的手机号是13512346789这个靓号,
不是15600998765,也是110或119,王大锤的手机号才是15600998765。
'''
# 查找所有匹配并保存到一个列表中
mylist = re.findall(pattern, sentence)
print(mylist)
print('--------华丽的分隔线--------')
# 通过迭代器取出匹配对象并获得匹配的内容
for temp in pattern.finditer(sentence):
print(temp.group())
print('--------华丽的分隔线--------')
# 通过search函数指定搜索位置找出所有匹配
m = pattern.search(sentence)
while m:
print(m.group())
m = pattern.search(sentence, m.end())
if __name__ == '__main__':
main()
说明: 上面匹配国内手机号的正则表达式并不够好,因为像14开头的号码只有145或147,而上面的正则表达式并没有考虑这种情况,要匹配国内手机号,更好的正则表达式的写法是:
(?<=\D)(1[38]\d{9}|14[57]\d{8}|15[0-35-9]\d{8}|17[678]\d{8})(?=\D)
,国内最近好像有19和16开头的手机号了,但是这个暂时不在我们考虑之列。
例子3:替换字符串中的不良内容
import re
def main():
sentence = '你丫是傻叉吗? 我操你大爷的. Fuck you.'
purified = re.sub('[操肏艹]|fuck|shit|傻[比屄逼叉缺吊屌]|煞笔',
'*', sentence, flags=re.IGNORECASE)
print(purified) # 你丫是*吗? 我*你大爷的. * you.
if __name__ == '__main__':
main()
说明: re模块的正则表达式相关函数中都有一个flags参数,它代表了正则表达式的匹配标记,可以通过该标记来指定匹配时是否忽略大小写、是否进行多行匹配、是否显示调试信息等。如果需要为flags参数指定多个值,可以使用按位或运算符进行叠加,如
flags=re.I | re.M
。
例子4:拆分长字符串
import re
def main():
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
sentence_list = re.split(r'[,。, .]', poem)
while '' in sentence_list:
sentence_list.remove('')
print(sentence_list) # ['窗前明月光', '疑是地上霜', '举头望明月', '低头思故乡']
if __name__ == '__main__':
main()
后话
如果要从事爬虫类应用的开发,那么正则表达式一定是一个非常好的助手,因为它可以帮助我们迅速的从网页代码中发现某种我们指定的模式并提取出我们需要的信息,当然对于初学者来收,要编写一个正确的适当的正则表达式可能并不是一件容易的事情(当然有些常用的正则表达式可以直接在网上找找),所以实际开发爬虫应用的时候,有很多人会选择Beautiful Soup或Lxml来进行匹配和信息的提取,前者简单方便但是性能较差,后者既好用性能也好,但是安装稍嫌麻烦,这些内容我们会在后期的爬虫专题中为大家介绍。