Python正規表現:文字セットおよび内部順序

6821 ワード

1.基礎内容
[](カッコ)正規表現の文字セットを記述するために使用され、文字セットの内部に文字を入力することで一致する内容をカスタマイズできます.
import re

regex1 = re.compile('[ABC]')
message1 = "Hello. This is ABC club. A man will serve you then."
print(regex1.findall(message1))

出力:[‘A’,‘B’,‘C’,‘A’]
正規表現は、カッコ内の任意の文字に基づいて一致します.
すべての大文字など、一致する文字が多い場合は、次のように操作できます.(ここでは、文字セットの使い方を説明するためです)
regex2 = re.compile('[A-Z]')
message2 = "It's my DUTY to save your SOUL."
print(regex2.findall(message2))

出力:[‘I’,‘D’,‘U’,‘T’,‘Y’]
数字や大文字など、他の内容にもマッチしたい場合は、次のようにします.
regex3 = re.compile('[0-9A-Z]')
message3 = "There are 7 GOBLINS and 2 dwarves in my house! Help!"
print(regex3.findall(message3))

出力:[‘T’,‘7’,‘G’,‘O’,‘B’,‘L’,‘I’,‘N’,‘S’,‘2’,‘H’]
0-9、A-Z間は離れません.マイナス記号'-'を一致させるには、エスケープ文字'-'を使用します.
2.内部手順
この文字セットの研究を続けると、「A-z」のような順序を使ってもいいかという疑問が生じました.
答えは肯定的だ.しかし、ここでは特別なことが起こります.
regex4 = re.compile('[A-z]')
message4 = "ABC Z [^] abc z"
print(regex4.findall(message4))

regex5 = re.compile('[M-m]')
message5 = "KLMNO...klmno"
print(regex5.findall(message5))

出力:[‘A’,‘B’,‘C’,‘Z’,‘[’,‘^’,‘],‘a’,‘b’,‘c’,‘z’][‘M’,‘N’,‘O’,‘k’,‘l’,‘m’]
うーん...何か記号が挿入されているようですね?
ここでは,[(c 1)−(c 2)]の構造については,ASCIIの順序に従って動作し,c 1からc 2の間(c 1とc 2を含む)のすべての文字に一致できることを示す結論が得られる.
検証してみましょう.
regex6 = re.compile('[#-E]')
message6 = "Awesome! The last 5% M&M Candies (10 candies) are nice; I'll enjoy them!"
print(regex6.findall(message6))

出力:[‘A’,‘5’,‘%’,‘&’,‘C’,‘(’,‘1’,‘0’,‘)’,‘;’,"""""""]---(最後は一重引用符)
ASCII表を確認:35-#,69-E
33 - !,37 - %,38 - &,39 - ',40 - (,41 - ) 48 - 0,49 - 1,53 - 5 59 - ; 65 - A,73 - I
したがって、基本的には、文字セットにおいて、‘−’を接続する文字順がASCIIの配列規則を満たす、すなわち、[(c 1)−(c 2)]に対して、対応するASCII値c 1<=c 2の場合、c 1からc 2の間の文字を一致させることが決定される.
[(c 1)-(c 2)]の順序を交換すると,c 1のASCII値がc 2より小さいとしたらどうなるかを検証する.
regex7 = re.compile('[a-Z]')
message7 = "Maybe it's wrong..."
print(regex7.findall(message7))

エラーメッセージが表示されます.
  • Traceback (most recent call last): File “G:/work/examples/eg_7_2.py”, line 27, in regex7 = re.compile(’[a-Z]’) File “D:\Python37\lib\re.py”, line 234, in compile return _compile(pattern, flags) File “D:\Python37\lib\re.py”, line 286, in _compile p = sre_compile.compile(pattern, flags) File “D:\Python37\lib\sre_compile.py”, line 764, in compile p = sre_parse.parse(p, flags) File “D:\Python37\lib\sre_parse.py”, line 930, in parse p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0) File “D:\Python37\lib\sre_parse.py”, line 426, in _parse_sub not nested and not items)) File “D:\Python37\lib\sre_parse.py”, line 580, in _parse raise source.error(msg, len(this) + 1 + len(that)) re.Error:bad character range a-Z at position 1(手動太字)
  • Process finished with exit code 1
    a-Zは文字セットマッチングの順序に合わない(a-97,Z-90,aのASCII値がZより大きいため)ため、問題が発生した.
    結論:文字セットは,"-"を接続する文字順でASCIIの配列規則を満たし,前後が大きい.