2017-09-30 5 views
0

正規のフォーム(XXX)XXX-XXXまたはXXX-XXX-XXXXで書かれた電話番号を追加条件付きで取得する機能を作成しようとしています。これは私がこのテストケース' (404) 555-1212 'を失敗していたが、SOの別の質問が(?:\)?\s*|-?)\)?\s*|-?を置き換えるために私を提案し、それが動作Python正規表現での目的(?:...)

def parse_phone2(s): 

    phone_number = re.compile(r'''^\s*\(?  # Begining of string, Ignore leading spaces 
            ([0-9]{3}) # Area code 
            \)?\s*|-?  # Match 0 or 1 ')' followed by 0 or more spaces or match a single hyphen 
            ([0-9]{3}) # Three digit 
            -?   # hyphen 
            ([0-9]{4}) # four digits 
            \s*$   # End of string. ignore trailing spaces''', re.VERBOSE) 
    try: 
     return (phone_number.match(s).groups()) 
    except AttributeError as e: 
     raise ValueError 

私のアプローチです。問題は、非キャプチャグループを作成すること以外に、(?:...)の目的と目的の違いを理解できないことです。ドキュメントは私にとっても十分明確ではありません。単にa sおよびb Sの(おそらく空の)文字列と一致

re.compile(r'(?:a|b)*') 

https://docs.python.org/3/library/re.html

+0

'(?:...)'は正規表現を構造化するのに使用できますが、通常の括弧とは異なり、キャプチャグループは作成されません。 –

+0

疑問符文字「?」は、1回または0回に一致します。あなたはそれを何かをオプションにすると考えることができます。たとえば、home-?brewは自家製または自家製のいずれかと一致します。 –

+0

@FadySaadそれは私の質問ではありません。私は '(?:\)?\ s * | - ?)'の代わりに '\)?\ s * | - ?' –

答えて

2

は単純な例を考えます。これと

re.compile(r'(a|b)*') 

間の唯一の違いは、マッチングエンジンは、group方法と検索にマッチした最初の文字を捕捉することです。非キャプチャグループを使用することは、キャプチャグループが不要な場合にマッチを高速化する(または少なくともメモリを節約する)最適化にすぎません。

2

置き換えた部分に代替トークンがあります。代替は、トークンの前にあるもの、または後にあるものと一致します。そして、あなたがここで行ったような行に正規表現を区切ることはグループ化とはみなされないので、同じ行の前後の行だけでなく前後の行にも一致するようにしようとします。

括弧でグループを囲んでグループ化する必要がありますが、デフォルトではグループを「取得」するので、groups()を呼び出すとグループの1つとして一致が返されます。すべきではないことを指定するには、?:を追加する必要があります。