目次
コラムガイド
コラム購読アドレス:https://blog.csdn.net/qq_35831906/category_12375510.html
1 正規表現の概要
Pythonの正規表現とは何なのか、その内容、機能、使い方は何なのか?
Python の正規表現は、モジュールを利用して文字列を操作するための強力なツールですre
。正規表現を使用すると、特定のパターンに基づいてテキスト データの照合、検索、置換、抽出を行うことができます。
正規表現の基本コンポーネントには次のものがあります。
- リテラル文字: 対応する文字に直接一致する、「a」、「b」などの通常の文字。
- メタキャラクター: 特別な意味を持つ文字。「.」は任意の文字に一致し、「\d」は数字に一致します。
- 修飾子: パターンの一致回数を指定するために使用されます。たとえば、「*」は 0 回以上一致、「+」は 1 回以上一致します。
- 文字クラス: 文字セット内の任意の文字と一致するために使用されます。たとえば、「[abc]」は「a」、「b」、または「c」と一致します。
- 文字を除外する: 指定した文字を除外するには、文字クラスで「^」を使用します。
- エスケープ文字: 特殊文字自体と一致させるために使用されます。たとえば、実際のドットと一致させるには「.」を使用します。
正規表現には、テキスト処理において多くの機能があります。
- パターン マッチング: 文字列に特定のパターンが含まれているかどうかを検索します。
- テキスト検索: 文字列内で最初に一致するパターンを検索します。
- すべて検索: 文字列内で一致するパターンをすべて検索し、一致するすべての結果のリストを返します。
- 分割: パターンに基づいて文字列を部分に分割します。
- 置換:パターンに一致する部分を指定した文字列に置換します。
正規表現を使用した簡単な例を次に示します。
import re
pattern = r'\d+' # 匹配一个或多个数字
text = "There are 123 apples and 456 oranges."
# 搜索
search_result = re.search(pattern, text)
if search_result:
print("Found:", search_result.group())
# 查找所有
findall_result = re.findall(pattern, text)
print(findall_result) # Output: ['123', '456']
上記のコードでは、関数は文字列内で一致するすべての数値
re.search()
を検索しながら、最初に一致する数値を検索します。re.findall()
正規表現を使用する場合は、発生する可能性のある例外の処理に注意しながら、パターンがターゲット テキストと正しく一致することを確認する必要があります。正規表現に精通しており、テキスト処理における効率的かつ柔軟なマッチング、検索、置換操作を実現できます。
2 正規表現の構文
2.1 正規表現の構文要素
行ロケータ、メタキャラクタ、修飾子、文字クラス、除外文字、選択文字、およびエスケープ文字は、正規表現の基本的な構成要素であり、文字列内のパターンの記述と一致に使用されます。
行ロケーター:
"^"
: 文字列の先頭と一致します。"$"
: 文字列の末尾と一致します。メタキャラクター:
"."
: 任意の文字 (改行を除く) と一致します。"\d"
: と同等の任意の数字に一致します[0-9]
。"\D"
: 数値以外の文字と一致し、 と同等です[^0-9]
。"\w"
: と同等の任意の文字、数字、またはアンダースコア文字と一致します[a-zA-Z0-9_]
。"\W"
: 英数字またはアンダースコア以外の文字と一致し、 と同等です[^a-zA-Z0-9_]
。"\s"
: スペース、タブ、改行などを含む任意の空白文字と一致します。"\S"
: 空白以外の文字と一致します。修飾子:
"*"
: 前の文字と 0 回以上一致します。"+"
: 前の文字と 1 回以上一致します。"?"
: 前の文字と 0 回または 1 回一致します。"{n}"
: 前の文字と正確に n 回一致します。"{n,}"
: 前の文字と少なくとも n 回一致します。"{n, m}"
: 前の文字と少なくとも n 回、最大 m 回一致します。文字クラス:
"[...]"
: 角括弧内の任意の文字と一致します。"[^...]"
: 角括弧内の文字を除く任意の文字と一致します。除外文字:
"^"
: 指定された文字を除外するために文字クラス内で使用されます。文字を選択します:
"|"
: 論理和。2 つのパターンのいずれかに一致します。エスケープ文字:
"\"
\.
: 特殊文字をエスケープして、実際のドットとの一致など、特別な意味を失うために使用されます。これらのメタキャラクタと特殊記号の組み合わせによって正規表現のパターンが形成されるため、正規表現で非常に複雑な文字列一致ルールを記述することができます。
re
正規表現を使用するには、 Python のモジュールが提供する一致、検索、置換などの関数を使用できます。これらの基本要素をよく理解すると、より強力で柔軟な正規表現を作成するのに役立ちます。
例:
import re
# 行定位符
pattern1 = r'^Hello' # 匹配以"Hello"开头的字符串
print(re.match(pattern1, "Hello, World!")) # Output: <re.Match object; span=(0, 5), match='Hello'>
pattern2 = r'World$' # 匹配以"World"结尾的字符串
print(re.search(pattern2, "Hello, World!")) # Output: <re.Match object; span=(7, 12), match='World'>
# 元字符
pattern3 = r'a.c' # 匹配"a"、任意字符、"c"
print(re.search(pattern3, "abc")) # Output: <re.Match object; span=(0, 3), match='abc'>
print(re.search(pattern3, "adc")) # Output: <re.Match object; span=(0, 3), match='adc'>
print(re.search(pattern3, "a,c")) # Output: <re.Match object; span=(0, 3), match='a,c'>
pattern4 = r'ab*' # 匹配"a"、"b"出现0次或多次
print(re.search(pattern4, "abbb")) # Output: <re.Match object; span=(0, 1), match='a'>
print(re.search(pattern4, "ac")) # Output: <re.Match object; span=(0, 0), match=''>
pattern5 = r'ab+' # 匹配"a"、"b"出现1次或多次
print(re.search(pattern5, "abbb")) # Output: <re.Match object; span=(0, 4), match='abbb'>
print(re.search(pattern5, "ac")) # Output: None
pattern6 = r'ab?' # 匹配"a"、"b"出现0次或1次
print(re.search(pattern6, "abbb")) # Output: <re.Match object; span=(0, 1), match='a'>
print(re.search(pattern6, "ac")) # Output: <re.Match object; span=(0, 0), match=''>
# 限定符
pattern7 = r'a{3}' # 匹配"a"出现3次
print(re.search(pattern7, "aaa")) # Output: <re.Match object; span=(0, 3), match='aaa'>
print(re.search(pattern7, "aaaa")) # Output: <re.Match object; span=(0, 3), match='aaa'>
print(re.search(pattern7, "aa")) # Output: None
pattern8 = r'a{3,5}' # 匹配"a"出现3次到5次
print(re.search(pattern8, "aaa")) # Output: <re.Match object; span=(0, 3), match='aaa'>
print(re.search(pattern8, "aaaaa")) # Output: <re.Match object; span=(0, 5), match='aaaaa'>
print(re.search(pattern8, "aaaaaa")) # Output: <re.Match object; span=(0, 5), match='aaaaa'>
# 字符类和排除字符
pattern9 = r'[aeiou]' # 匹配任意一个小写元音字母
print(re.search(pattern9, "apple")) # Output: <re.Match object; span=(0, 1), match='a'>
print(re.search(pattern9, "banana")) # Output: <re.Match object; span=(1, 2), match='a'>
print(re.search(pattern9, "xyz")) # Output: None
pattern10 = r'[^0-9]' # 匹配任意一个非数字字符
print(re.search(pattern10, "hello")) # Output: <re.Match object; span=(0, 1), match='h'>
print(re.search(pattern10, "123")) # Output: None
# 转义字符
pattern11 = r'\.' # 匹配句号
print(re.search(pattern11, "www.example.com")) # Output: <re.Match object; span=(3, 4), match='.'>
# 分组
pattern12 = r'(ab)+' # 匹配"ab"出现1次或多次作为一个整体
print(re.search(pattern12, "ababab")) # Output: <re.Match object; span=(0, 6), match='ababab'>
出力には、一致した部分文字列の開始位置と終了位置、および一致した実際の文字列の内容が表示されます。
一般的なメタキャラクター
共通修飾子
2.2正規表現のグループ化操作
正規表現におけるグループ化は、複数のサブパターンを組み合わせて個別に処理するためのメカニズムです。括弧を使用してグループ化を作成すると()
、より複雑な照合および抽出操作を実行できます。
グループ化機能には次のものが含まれます。
-
優先順位制御: グループ化を使用してサブパターンの優先順位を変更し、正しい一致順序を確保できます。
-
サブパターンの再利用: サブパターンに名前を付け、後続の正規表現でその名前を参照すると、同じパターンを再利用できます。
-
サブパターン抽出: コンテンツのさらなる処理を容易にするために、一致する部分文字列をグループ化して抽出できます。
例:
import re
text = "John has 3 cats and Mary has 2 dogs."
# 使用分组提取匹配的数字和动物名称
pattern = r'(\d+)\s+(\w+)' # 使用括号创建两个分组:一个用于匹配数字,另一个用于匹配动物名称
matches = re.findall(pattern, text) # 查找所有匹配的结果并返回一个列表
for match in matches:
count, animal = match # 将匹配结果拆分为两个部分:数字和动物名称
print(f"{count} {animal}")
# 使用命名分组
pattern_with_name = r'(?P<Count>\d+)\s+(?P<Animal>\w+)' # 使用命名分组,给子模式指定名称Count和Animal
matches_with_name = re.findall(pattern_with_name, text) # 查找所有匹配的结果并返回一个列表
for match in matches_with_name:
count = match['Count'] # 通过名称获取匹配结果中的数字部分
animal = match['Animal'] # 通过名称获取匹配结果中的动物名称部分
print(f"{count} {animal}")
上記のコードは、グループ化を使用して正規表現内の一致した部分文字列を抽出する方法を示しています。最初の正規表現は、通常のグループ化を使用して、括弧を介して数字と動物の名前を個別に抽出します。2 番目の正規表現は名前付きグループ化を使用し、
(?P<Name>...)
使用される文法形式でサブパターンの名前を指定するため、一致結果の名前によって対応する部分文字列を取得できます。これにより、コードが読みやすくなり、その後の処理や一致結果の使用が容易になります。
上記のコードは次のようにエラーを報告します。
「TypeError: タプル インデックスは str ではなく、整数またはスライスである必要があります。」 このエラーは、コードがタプル インデックスとして文字列を使用しようとしているが、タプル インデックスは整数またはスライスのみであることを意味します。
タプルを使用する場合、タプル内の要素を取得するには、次のような整数またはスライスを使用する必要があります。
my_tuple[0]
またはmy_tuple[1:3]
、これらは正当なインデックス付け方法です。ただし、文字列を使用してタプル内の要素にインデックスを付けようとすると、次のようになりmy_tuple['key']
ます。タプルには文字列インデックスに関連付けられたキーと値のペアがないため、これは無効です。
訂正: でマッチング結果の内容を取得してください。re.finditer()替代第二个 re.findall(),用match.group()
更正后代码:
import re
text = "John has 3 cats and Mary has 2 dogs."
# 使用分组提取匹配的数字和动物名称
pattern = r'(\d+)\s+(\w+)' # 使用括号创建两个分组:一个用于匹配数字,另一个用于匹配动物名称
matches = re.findall(pattern, text) # 查找所有匹配的结果并返回一个列表
for match in matches:
count, animal = match # 将匹配结果拆分为两个部分:数字和动物名称
print(f"{count} {animal}")
# 使用命名分组
pattern_with_name = r'(?P<Count>\d+)\s+(?P<Animal>\w+)' # 使用命名分组,给子模式指定名称Count和Animal
matches_with_name = re.finditer(pattern_with_name, text) # 使用re.finditer()查找所有匹配的结果
for match in matches_with_name:
count = match.group('Count') # 通过名称获取匹配结果中的数字部分
animal = match.group('Animal') # 通过名称获取匹配结果中的动物名称部分
print(f"{count} {animal}")
ノート:
re.findall()
どちらもre.finditer()
Python で正規表現を照合するための関数であり、両者の違いは返される結果の型が異なることです。
re.findall(pattern, string)
:findall
この関数は、正規表現に一致するすべての結果をpattern
リストの形式で返します。各一致結果はリスト内の文字列要素として保存されます。正規表現にグループが含まれている場合、findall
完全な一致結果ではなく、グループ内のコンテンツのみが返されます。
re.finditer(pattern, string)
:この関数は、finditer
正規表現pattern
に一致するすべての結果も返しますが、それとは異なりfindall
、finditer
反復子を返します。group()
各 iterator オブジェクトはマッチング結果を表し、マッチング結果の内容はiterator メソッドを通じて取得できます。正規表現にグループがある場合、group()
メソッドを使用して各グループの内容にアクセスできます。要約すると、
re.findall()
リストが返されるのに対し、re.finditer()
イテレータは返されます。複数の一致結果を処理する必要がある場合、finditer
すべての一致結果を一度に返すのではなく、必要に応じてオンデマンドで提供するため、より柔軟で効率的に使用できます。
3 つのモジュールの詳細と例
re
このモジュールは、正規表現を処理するための Python の組み込みモジュールであり、文字列の一致、検索、置換、分割のための一連の関数を提供します。re
このモジュールの主な機能は次のとおりです。
re.compile(pattern, flags=0)
: 正規表現パターンをコンパイルし、正規表現オブジェクトを返します。同じ正規表現を複数回使用する場合は、この関数を使用してプリコンパイルし、パフォーマンスを向上させることができます。
re.match(pattern, string, flags=0)
: 文字列の先頭からパターンの照合を試み、照合が成功した場合は match オブジェクトを返し、それ以外の場合は None を返します。
re.search(pattern, string, flags=0)
: 文字列全体で最初に一致するパターンを検索し、一致した場合は match オブジェクトを返し、それ以外の場合は None を返します。
re.findall(pattern, string, flags=0)
: 文字列内で一致するパターンをすべて検索し、一致するすべての結果のリストを返します。
re.finditer(pattern, string, flags=0)
: 文字列内で一致するパターンをすべて検索し、反復子を返します。反復子を通じて一致するオブジェクトを取得できます。
re.split(pattern, string, maxsplit=0, flags=0)
: パターンに従って文字列を複数の部分に分割し、リストを返します。
re.sub(pattern, replacement, string, count=0, flags=0)
: パターンに一致する部分を指定された文字列に置換し、置換後の文字列を返します。
上記の関数で、pattern
は正規表現のパターン、string
は照合または処理される文字列、flags
はオプションのパラメータで、正規表現の修飾子の指定に使用されます。その中で、大文字と小文字の区別や複数行の一致を指定するためにflags
使用するなど、複数の修飾子を使用してパラメータを組み合わせることができますre.IGNORECASE | re.MULTILINE
。
次の例は、re
モジュール内のさまざまな関数の使用法を示し、一致、検索、置換、分割、名前付きグループ化などの関数をカバーしています。
import re
text = "John has 3 cats, Mary has 2 dogs."
# 使用re.search()搜索匹配模式的第一个出现
pattern_search = r'\d+\s+\w+'
search_result = re.search(pattern_search, text)
if search_result:
print("Search result:", search_result.group()) # Output: "3 cats"
# 使用re.findall()查找所有匹配模式的出现,并返回一个列表
pattern_findall = r'\d+'
findall_result = re.findall(pattern_findall, text)
print("Find all result:", findall_result) # Output: ['3', '2']
# 使用re.sub()将匹配模式的部分替换为指定的字符串
pattern_sub = r'\d+'
replacement = "X"
sub_result = re.sub(pattern_sub, replacement, text)
print("Sub result:", sub_result) # Output: "John has X cats, Mary has X dogs."
# 使用re.split()根据模式将字符串分割成多个部分
pattern_split = r'\s*,\s*' # 匹配逗号并去除前后空格
split_result = re.split(pattern_split, text)
print("Split result:", split_result) # Output: ['John has 3 cats', 'Mary has 2 dogs.']
# 使用命名分组
pattern_named_group = r'(?P<Name>\w+)\s+has\s+(?P<Count>\d+)\s+(?P<Animal>\w+)'
matches_with_name = re.finditer(pattern_named_group, text)
for match in matches_with_name:
name = match.group('Name')
count = match.group('Count')
animal = match.group('Animal')
print(f"{name} has {count} {animal}")
# 使用re.compile()预编译正则表达式
pattern_compile = re.compile(r'\d+')
matches_compiled = pattern_compile.findall(text)
print("Compiled findall result:", matches_compiled) # Output: ['3', '2']
上記の例は、正規表現の一致、検索、置換、分割、および名前付きグループ化のためのモジュールの使用法を示しています
re
。コメントは各ステップの機能と予想される出力を説明しており、正規表現を合理的に使用することで、文字列の複雑な処理要件を迅速に実現できます。
4 正規表現修飾子
Python の正規表現では、修飾子 (フラグまたはモード フラグとも呼ばれる) は、正規表現のコンパイル時に関数に渡すか、re.compile()
正規表現文字列で直接使用して一致動作を変更できるオプションのパラメーターです。
一般的に使用される正規表現修飾子は次のとおりです。
re.IGNORECASE
またはre.I
: 大文字と小文字の一致を無視します。この修飾子を使用すると、照合時に大文字と小文字の違いを無視できます。
re.MULTILINE
またはre.M
: 複数行の一致。この修飾子を使用すると、^
文字$
列の先頭と末尾がそれぞれ一致し、文字列の各行の先頭と末尾も一致します (各行は改行で区切られます)。
re.DOTALL
またはre.S
: 単一行の一致。この修飾子を使用すると、.
改行を含む任意の文字が一致します。
re.ASCII
またはre.A
: 非 ASCII 文字を対応する ASCII 文字のみと一致させます。たとえば、\w
ASCII 文字、数字、アンダースコアのみに一致しますが、非 ASCII 文字には一致しません。
re.UNICODE
またはre.U
: Unicode マッチングを使用します。Python 3 では、正規表現はデフォルトで Unicode マッチングを使用します。
re.VERBOSE
またはre.X
: 「より読みやすい」正規表現を使用します。コメントと空白を式に追加すると、正規表現が読みやすくなります。
Python では、正規表現修飾子 (フラグとも呼ばれます) は、正規表現の一致動作を調整するために使用されるオプションのパラメーターです。正規表現パターンの末尾に修飾子を追加して、パターンの一致方法に影響を与えることができます。一般的に使用される正規表現修飾子は次のとおりです。
次の例は、これらの修飾子の使用法を示しています。
import re
# 不区分大小写匹配
pattern1 = r'apple'
text1 = "Apple is a fruit."
match1 = re.search(pattern1, text1, re.I)
print(match1.group()) # Output: "Apple"
# 多行匹配
pattern2 = r'^fruit'
text2 = "Fruit is sweet.\nFruit is healthy."
match2 = re.search(pattern2, text2, re.M)
print(match2.group()) # Output: "Fruit"
# 点号匹配所有字符
pattern3 = r'apple.*orange'
text3 = "apple is a fruit.\noranges are fruits."
match3 = re.search(pattern3, text3, re.S)
print(match3.group()) # Output: "apple is a fruit.\noranges"
# 忽略空白和注释
pattern4 = r'''apple # This is a fruit
\s+ # Match one or more whitespace characters
is # followed by "is"
\s+ # Match one or more whitespace characters
a # followed by "a"
\s+ # Match one or more whitespace characters
fruit # followed by "fruit"'''
text4 = "Apple is a fruit."
match4 = re.search(pattern4, text4, re.X)
print(match4.group()) # Output: "apple is a fruit"