パイソン
1正規表現のコンセプト
正規表現(RE)REモジュールによって達成されるPythonで小さな、高度に専門化プログラミング言語、です。
正規表現は、以下の機能を実現することができます。
- 試合にしたい文字列の対応する設定のための規則を指定します。
- 可変長文字セットと一致することができ;
- あなたは、正規表現の部分の繰り返し回数を指定することができます。
- REは、様々な修正するための方法または分割文字列で使用することができます
正規表現パターンは、バイトコードの系列にコンパイルCで書かれ、次いで、マッチングエンジンを実行しています。
2一致する文字
2.1普通の文字:
ほとんどの文字と文字の一般、自分の試合。
正規表現のテスト意志の文字列「テスト」として、完全一致
import re
r = re.findall('el','hello world')
print(r)
2.2元の文字:^ $ * + {} [] |()\。?
2.2.1元の文字。
以外の任意の単一の改行文字(\ n)を合わせて、デフォルトの追加
指定したフラグDOTALLは、それが任意の1文字と一致し、コンパイラは、改行が含まれて
import re
ret = re.findall('r..time', 'helloruntime')
print(ret) # ['runtime']
2.2.2メタキャラクタ^
^行を一致させるために使用されます。MULTILINEフラグが設定されていない限り、それは文字列の一致の始まりに過ぎだ
MULTILINEモードでは、それはまた、文字列の各ラインフィードに直接一致させることができます
import re
ret = re.findall('^r..time', 'hellorootime')
print(ret) # []
ret = re.findall('^h..lo', 'hellorootime')
print(ret) # ['hello']
$メタ文字の2.2.3
行の末尾に一致するように$は、行の最後には、文字列のどちらかの端、またはラインフィード文字の後ろの任意の位置として定義されます
import re
ret = re.findall('time$', 'hellorootime')
print(ret) # ['time']
2.2.4メタキャラクタ*
- 一度だけ指定するのではなく、ために使用される前に、文字が0回以上一致させることができます。
マッチングエンジンは、(スコープを定義する整数、2000000000を超えないように)何回も繰り返すことしようとします
import re
ret=re.findall('abc*','abcccc') # 贪婪匹配[0,+oo]
print(ret) # ['abcccc']
ret=re.findall('abc*','ab')
print(ret) # ['ab']
+の2.2.5メタキャラクタ
- これは、少なくとも1回以上を示すために使用しました
import re
ret=re.findall('abc+','abcccc') #[1,+oo]
print(ret) # ['abcccc']
ret=re.findall('abc+','ab')
print(ret) # []
2.2.6メタキャラクタの?
?1または0を一致させるために使用される:あなたは何かをマークすると考えることができ、オプションされて
繰り返し(+と*)の後に加え、あなたは最小一致を達成するために、レイジー・モードを有効にすることができます
import re
ret=re.findall('abc?','abccc') # [0,1]
print(ret) # ['abc']
ret=re.findall('abc*?','abccc') # [0]
print(ret) # ['ab']
ret=re.findall('abc+?','abccc') # [1]
print(ret) # ['abc']
注:?*と+フロントとすべての貪欲マッチングされ、マッチングが可能であり、それは不活性試合になるように、プラス記号が続きますか?
2.2.7のメタキャラクタ{M、N}
{M、N}は、mおよびnは小数点整数で指定された回数を、一致します。修飾子手段Nまで繰り返す少なくともm個のリピートを有します
省略mはN、下限が0で解釈され、無限の境界にあろう結果を無視している(実際には20億)
等しい{0 *}は、{1} + {0,1}に等しいと同じです?。可能であれば、それは*、+を使用するのが最善ですか?
import re
ret=re.findall('abc{1,3}','abccc')
print(ret) # ['abccc']
ret=re.findall('abc{1,3}','abc')
print(ret) # ['abc']
ret=re.findall('abc{1,3}','ab')
print(ret) # []
ret=re.findall('abc{0,}','abccccc')
print(ret) # [abccccc]
ret=re.findall('abc{0,1}','abccccc')
print(ret) # [abc]
ret=re.findall('abc{1}','abccccc')
print(ret) # [abc]
ret=re.findall('abc{1,3}','abccccccccc')
print(ret) # ['abccc']
[]の2.2.8メタキャラクタ
[]は、文字セットを指定するために使用します:[ABC]または[AZ]
文字中の元素濃度は動作しません:[AKM $]
[]内に試合の始まりは文字の範囲によって表される範囲内ではありません:[ AZ]
import re
ret = re.findall('a[bc]d', 'acd')
print(ret) # ['acd']
ret = re.findall('[a-z]', 'acd')
print(ret) # ['a', 'c', 'd']
ret = re.findall('[.*+]', 'a.cd+')
print(ret) # ['.', '+']
# 在字符集里有功能的符号: - ^ \
ret = re.findall('[1-9]', '45dha3')
print(ret) # ['4', '5', '3']
ret = re.findall('[^ab]', '45bdha3')
print(ret) # ['4', '5', 'd', 'h', '3']
ret = re.findall('[\d]', '45bdha3')
print(ret) # ['4', '5', '3']
2.2.9メタ文字\
バックスラッシュは異なる特別な意味を表すために、異なる文字にすることができます
元とバックスラッシュ文字の後ろなどの特殊な機能を、削除します。
バックスラッシュを、このような\ dと通常の文字、との特別な機能の実現の後ろ
ret = re.findall('I\b','I am LIST')
print(ret) # []
ret = re.findall(r'I\b','I am LIST')
print(ret) # ['I']
今、私たちは、以下の2つの試合を見て、チャット
#-----------------------------egg1:
import re
ret = re.findall('c\l','abc\le')
print(ret) # []
ret = re.findall('c\\l','abc\le')
print(ret) # []
ret = re.findall('c\\\\l','abc\le')
print(ret) # ['c\\l']
ret = re.findall(r'c\\l','abc\le')
print(ret) # ['c\\l']
#-----------------------------egg2:
#之所以选择\b是因为\b在ASCII表中是有意义的
m = re.findall('\bblow', 'blow')
print(m)
m = re.findall(r'\bblow', 'blow')
print(m)
2.2.10グループ化メタ文字()
()すなわち、いくつかのデータパケットは、全体に分割することができる
だけ戻されたデータパケットの場合のfindAllパケットを照合するために使用される場合
email = r'\w+@\w+\.(com|cn|com\.cn)'
m = re.findall(r'(ad)+', 'add')
print(m)
n = re.findall(r'(ad)+', 'adaad')
print(n)
ret=re.search('(?P<id>\d{2})/(?P<name>\w{3})','23/com')
print(ret.group()) # 23/com
print(ret.group('id')) # 23
print(ret.group('name')) # com
2.2.11メタキャラクタ|
|左または右の文字「|」一致させるために使用される
グループメソッドの戻り値になって、ヒットする内容と一致するように指定した文字列で
ret = re.search('(ab)|\d','rabhdg8sd')
print(ret.group()) # ab
ret = re.search('(hello)|(world)','abcworldhhahello')
print(ret.group()) # world
3の正規表現コンパイラ
re模块提供了一个正则表达式引擎的接口re.compile()函数,可将RE string编译成对象并用它们来进行匹配。
编译后的正则要比没编译而直接解释的正则处理速度要快很多。
编译正则表达式
import re
phone_number = re.compile('^\d{3,4}-?\d{8}$')
print(phone_number) # <_sre.SRE_Pattern object at 0x7f672ed46300>
print(phone_number.findall('010-12345678')) # ['010-12345678']
print(phone_number.findall('010-123456789')) # []
print(phone_number.findall('0120-12345678')) # ['0120-12345678']
re.compile()也接受可选的标志参数,常用来实现不同的特殊功能和语法变更。
p = re.compile(r'ab*',re.IGNORECASE)
编译标志-flags:后面的单个字母可以代替前面的单词,如re.S可以代替re.DOTALL
3.1 执行匹配常用的函数
'RegexObject’实例有一些方法和属性,完整的列表可查阅Python Library Reference
- match():决定RE是否在字符串刚开始的位置匹配
- search():扫描字符串,找到这个RE匹配的位置,无论在字符串的什么位置均能找到
- findall():找到RE匹配的所有子串,并把它们作为一个列表返回
- finditer():找到RE匹配的所有子串,并把它们作为一个迭代器返回
注意:若未匹配到则match()和search()将返回None。若匹配成功则返回一个’MatchObject’实例对象
MatchObject实例方法:
- group():返回被RE匹配的字符串
- groupdict():将匹配的结果与给定的key生成一个字典并打印
- start():返回匹配开始的位置
- end():返回匹配结束的位置
- span():返回一个元组包含匹配(开始,结束)的位置
import re
ret = re.search('(?P<id>[0-9]+)','abc1234daf@34')
print(ret.group()) # 1234
print(ret.groupdict()) # {'id': '1234'}
print(ret.start()) # 3
print(ret.end()) # 7
print(ret.span()) # (3, 7)
实际程序中,最常见的方法是将’MatchObject’保存在一个变量里,然后检查它是否为None。
import re
p = re.compile('(?P<id>[0-9]+)')
m = p.match('abc1234daf@34')
if m:
print('Match found: ',m.group())
else:
print('No match')
3.2 模块级函数
re模块也提供了顶级函数调用,如match()、search()、sub()、subn()、split()、findall()等
3.2.1 sub()与subn()
文字列文字列に適用される正規表現パターン、与えられ、REPLにコンテンツをマッチング
re.sub(パターン、REPL、ストリング、COUNT = 0)は、
ハローワールドハローパイソンに変更されます
import re
ret = re.sub(r'w...d','python','hello world')
print(ret) # hello python
ret = re.sub(r'w...d','python','hello world world world wordd',2)
print(ret) # hello python python world wordd
# subn返回一个匹配到的内容与匹配次数的元组
ret = re.subn(r'w...d','python','hello world world wordd')
print(ret) # ('hello python python python', 3)
3.2.2スプリット()
セグメント文字列に演技した、正規表現パターンを考えると
re.split(パターン、文字列)
* +区切られた文字列の後ろに分割される-に
import re
ret = re.split('[-+*]','123+456-789*000')
print(ret) # ['123', '456', '789', '000']
ret = re.split('[ab]','haabcd') # 先按'a'分割得到'h',''和'bcd',再对'h',''和'bcd'分别按'b'分割
print(ret) # ['h', '', '', 'cd']
[ - +]に[±]それはできますか?
3.2.3のfindAll()
リストに、すべての結果がルールに一致戻ります
import re
ret = re.findall('e','sean cheng')
print(ret) # ['e', 'e']
ret = re.findall('www.(baidu|runtime).com', 'www.runtime.com')
print(ret) # ['runtime'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ret = re.findall('www.(?:baidu|runtime).com', 'www.runtime.com')
print(ret) # ['www.runtime.com']
ret = re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
print(ret) # ['h1']
3.2.4検索()
一致する文字列、なしが返されない場合、それが一致を見つけてマッチング情報を含む最初のオブジェクトを返すまでの文字列を見つけるためにパターンマッチングは、本方法は、()のグループにマッチする文字列を呼び出すことによって得ることができます
import re
ret = re.search('e','sean cheng').group()
print(ret) # e
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
print(ret.group()) # <h1>hello</h1>
ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
print(ret.group()) # <h1>hello</h1>
3.2.5一致()
同じ検索が、唯一の文字列一致の先頭に
import re
ret = re.match('s','sean cheng').group()
print(ret)
3.2.6スプリット()
リターンマッチング結果に反復子を形成し、次の方法の結果が除去イテレータで使用することができ、それはまた、順次除去ループのために使用することができます
import re
ret = re.finditer('\d', 'ds3sy4784a')
print(ret) # <callable_iterator object at 0x0000000002100AC8>
# print(next(ret).group()) # 3
# print(next(ret).group()) # 4
# print(next(ret).group()) # 7
for i in ret:
print(i.group())