

以下のコードについての質問です。「[退屈なことはpythonにやらせよう](https://www.oreilly.co.jp/books/9784873117782/)」の7章を参考に、コピーしたテキストから電話番号とメールアドレスを抽出してリストにまとめるコードなのですが、

[code]

    for groups in phone_regex.findall(text):
    
[/code]

この部分では、いったいgroupsはどういったものに変化していくのでしょうか。  
（`for i in range(0,100)` の場合 `i` は ０－９９に変化する という感じ）

また どうして

[code]

    phone_num = '-'.join([groups[1],groups[3],groups[5]])
    
[/code]

は `group(1)` ではなく `groups[1]` （ｓがつく）のでしょうか。

[code]

    import pyperclip as pcl
    import re
    
    phone_regex =re.compile(r'''(
        (\d{1,4}|\(\d{1,4}\))           #市外局番
        (\s|-)                          #区切り
        (\d{1,4})                       #市内局番
        (\s|-)                          #区切り
        (\d{3,4})                       #加入者番号
        (\s*(ext|x|ext.)\s*(\d{2,5}))?  #内線番号
        )''',re.VERBOSE)
    
    email_regex = re.compile(r'''(
        [a-zA-Z0-9._%+-]+       #ユーザー名
        @
        [a-zA-Z0-9.-]+          #ドメイン名
        (\.[a-zA-Z]{2,4})       #.after
        )''',re.VERBOSE)
    
    #クリップボードのテキストを検索する
    text = (pcl.paste())
    matches = []
    for groups in phone_regex.findall(text):
        phone_num = '-'.join([groups[1],groups[3],groups[5]])
        if groups[8] != '':
            phone_num += ' x' + groups[8]
        matches.append(phone_num)
    for groups in email_regex.findall(text):
        matches.append(groups[0])
    
    if len(matches)>0:
        pcl.copy('\n'.join(matches))
        print('コピーしました')
        print('\n'.join(matches))
    else:
        print('電話番号やメールアドレスは見つかりませんでした')
    
[/code]


CC BY-SA 4.0
2018-10-13T06:52:48.677
49240
2018-10-15T07:19:15.307
2018-10-13T08:16:14.733
3060
30505
question
python
正規表現を用いた電話番号とメールアドレスの抽出について


`phone_regex.findall(text)`がどういうものになるかについては、結論からいうとタプルのリストになります。

例えば、textに`03-1111-2222`,`03-3333-4444`が含まれていると次のようになります。タブルは、正規表現にマッチした文字列と正規表現での8個のグループからできています。

[code]

    [('03-1111-2222', '03', '-', '1111', '-', '2222', '', '', ''), ('03-3333-4444', '03', '-', '3333', '-', '4444', '', '', '')
    
[/code]

それで、`groups`には、リストにある順番（テキストにある順番）で、正規表現にマッチ電話番号とその正規表現でのグループからできたタプルが代入されます。タプルはシーケンス型なので`groups[1]`のようにして要素を取得します。なぜ、group
ではなく groups としているのかというと、正規表現でのグループを複数含むためと思われます。

詳しくは、公式ドキュメントの [re ---
正規表現操作](https://docs.python.org/ja/3.7/library/re.html)から、`(...)`と`re.findall`の部分を引用しておきますので、公式ドキュメントをみてください。

> (...)  
>
> 丸括弧で囲まれた正規表現にマッチするとともに、グループの開始と終了を表します。グループの中身は以下で述べるように、マッチが実行された後で回収したり、その文字列中で以降
> \number 特殊シーケンスでマッチしたりできます。リテラル '(' や ')' にマッチするには、( や ) を使うか、文字クラス中に囲みます:
> [(]、 [)] 。

> re.findall(pattern, string, flags=0)  
>  string 中の pattern による全ての重複しないマッチを、文字列のリストとして返します。 string
> は左から右へ走査され、マッチは見つかった順で返されます。パターン中に 1
> つ以上のグループがあれば、グループのリストを返します。パターンに複数のグループがあればタプルのリストになります。空マッチは結果に含まれます。


CC BY-SA 4.0
2018-10-14T13:23:50.007
49273
2018-10-15T07:19:15.307
2018-10-15T07:19:15.307
15171
15171
49240
answer