デカ文字Python

デカ文字&短文でPythonを簡潔にまとめたブログ

Python SoloLearn Regular Expressions③

f:id:pokita:20181013095615p:plain

 

今回は思うところ特にないです。

 

 

Groups

グループとは

A group can be created by surrounding part of a regular expression with parentheses.
This means that a group can be given as an argument to metacharacters such as * and ? .

 

特殊文字を関数、()で括ったグループを引数とする考え、面白い。

 

group関数

The content of groups in match can be accessed using group function.

 

()で括ることでグループ化できる。 グループを含むmatchオブジェクトは数字の引数で呼び出すことができる。

import re

pattern = r"a(bc)(de)(f(g)h)i"
m = re.match(pattern, "abcdefghigklmn")

print(m.group(1))
>>>bc

 

 Named groups have the format (?P<name>…),where name is the name of group, and … is content. They can be accessed by group(name) in addition to its number.

 

また、グループ化する際には?P<name>を付けることで"name"を引数にグループを呼び出すことができる。

import re

pattern = r"(?P<first>abc)(?:def)(ghi)"
m = re.match(pattern, "abcdefghi")

print(m.group("first"))
>>>abc

 

Special Sequences

There are various special sequences you can use in regular expressions.
They are written as a backslash followed by another character..

 

バックスラッシュ\を使うことで、特殊文字みたいな機能が使えるのかぁ…
ってこれエスケープシーケンスを避けたr""内でもできるっておかしくない?

 

わかってはいるが割り切ることできない…

 

 一覧はここ公式ドキュメントで確認。

import re

source = "SPAM!"

m1 = re.match(r"\ASPAM!\Z", source)
m2 = re.match(r"\AS...\b.\Z", source)#\bはここでは文字列と!の間を表す。
m3 = re.match(r"\A(SP)AM!\Z", source)

print(m1)
>>><_sre.SRE_Match object; span=(0, 5), match='SPAM!'>

print(m2)
>>><_sre.SRE_Match object; span=(0, 5), match='SPAM!'>

print(m3)
>>><_sre.SRE_Match object; span=(0, 5), match='SPAM!'>

 

 \number

Backslash and a number between 1 and 99 is useful special swquence.
This matches the expression of the group of that number.

 

????????????????????????

 

以下に続く例文がこれ。

import re

pattern =r"(.+) \1"
m1 = re.match(pattern, "word word")

print(m1)
>>><_sre.SRE_Match object; span=(0, 9), match='word word'>

m2 = re.match(pattern ,"wordword")

print(m2)
>>>None

 

??????????????・??・/????

 

これは例文が悪い。これじゃあ何が言いたいかわからない(少なくとも私文のぼくは)

 

そういうわけで、例文を自分なりに書き直してみた。

import re

pattern = r"(ham)(spam)(egg) \1"
m = re.match(pattern, "hamspamegg ham")

print(m)
>>><_sre.SRE_Match object; span=(0, 14), match='hamspamegg ham'>

 

patternは正規表現内では"(ham)(spam)(egg) "+"スペース"+"ham(第一グループ)"のhamspamegg hamと表さられる。

 

Pycharmを触っていたら(group)* ≠ (group)\1 なことにも気づいたのでついでにメモ。

import re

pattern1 = r"(ham|spam)\1"
pattern2 = r"(ham|spam)*"

m1 = re.match(pattern1, "hamspam")
m2 = re.match(pattern2, "hamspam")

print(m1)
>>>None

print(m2)
>>><_sre.SRE_Match object; span=(0, 7), match='hamspam'>

 

\1の場合、元の(group)でhamとなったら、後で呼び出された\1もhamとなる。

一方、*は元の(group)がhamになろうとも、その後呼び出されるのは(group)のコピーである(ham|spam)であるため"hamspam"という並びが可能となる。

 

Email Extraction

 

import re

str = "Please contact info@sololearn.com for assistance."
pattern = r"([\w\.-]+)@([\w\.-]+)(\.[\w\.-]+)"

match = re.search(pattern, str)
if match:
print(match.group())
>>>info@sololearn.com

 

このコードにおける正規表現r"([\w\.-]+)@([\w\.-]+)(\.[\w\.-]+)"の解説。

()

特に意味がない。他の要素との区切りを表す機能がある。

(abc) = abc

[]

中に入っている要素のどれか一つを表す。

[abc] = a or b or c

\w

文字を表す。

\w = a-z

\.

文字としての"."を表す。"."単体ならなんでもありの正規表現なので。

\. = "."

+

前の要素の一回以上の繰り返しを表す。

a+ = a ,or aa ,or aaa , or aaaa..........

 

よってr"([\w\.-]+)@([\w\.-]+)(\.[\w\.-]+)"で、Email配列を切り抜くことができる。

 

今回はここまで。