ホームページ >バックエンド開発 >PHPチュートリアル >PHPの正規表現が引っかからない
PHP 正規表現は
をキャプチャしません
出典: http://www.iq662.com
置換
さて、いよいよ 3 桁または 4 桁の市外局番の問題を解決します。正規表現での置換は、これらのルールのいずれかが一致する場合、異なるルールを | で区切って行うことを意味します。分かりませんか?それは問題ではありません。例を見てください:
0d{2}-d{8}|0d{3}-d{7} この式は、ハイフンで区切られた 2 つの電話番号に一致します。1 つは 3 です。 1 つは市外局番、8 桁の市内番号 (010-12345678 など)、もう 1 つは 4 桁の市外局番、7 桁の市内番号 (0376-2233445) です。
(0d{2})[- ]?d{8}|0d{2}[- ]?d{8} この式は、3 桁の市外局番を持つ電話番号と一致します。コードは括弧で囲むことができます。括弧は使用してもしなくても構いません。市外局番と市内局番はハイフンまたはスペースで区切ることも、区切らないこともできます。 replace | を使用してこの式を拡張し、4 桁の市外局番もサポートしてみることができます。
d{5}-d{4}|d{5} は、米国の郵便番号を照合するために使用される式です。米国の郵便番号の規則は 5 桁、またはハイフンで区切られた 9 桁です。この例が挙げられている理由は、問題を説明するためです。置換を使用する場合、順序は非常に重要です。これを d{5}|d{5}-d{4} に変更すると、5 桁の郵便番号 (および 9 桁の郵便番号の最初の 5 桁) のみが照合されます。その理由は、照合および置換の際に、各条件が左から右にテストされ、特定の条件が満たされた場合、他の置換条件は考慮されないためです。
Windows98|Windows2000|WindosXP この例は、置換が 2 種類のルールだけでなく、より多くの種類のルールにも使用できることを示しています。
グループ
単一の文字を繰り返す方法についてはすでに説明しましたが、文字列を繰り返す場合はどうすればよいでしょうか。かっこを使用して部分式 (グループ化とも呼ばれます) を指定し、この部分式の繰り返し数を指定できます。また、部分式に対して他の操作を実行することもできます (これについては、チュートリアルで後ほど説明します)。
(d{1,3}.){3}d{1,3} は、単純な IP アドレス一致式です。この式を理解するには、次の順序で分析してください。 d{1,3} は 1 ~ 3 桁の数値を表します (d{1,3}。{3} は 3 桁の数値とピリオドを表します (この全体がこのグループ化です) を 3 回繰り返し、最後に 1 ~ 3 桁の数字 (d{1,3}) が追加されます。残念ながら、これは 256.300.888.999 の可能性のある IP アドレスにも一致します。算術比較を使用できる場合は、この問題を簡単に解決できる可能性がありますが、正規表現では数学関数が提供されないため、説明には長いグループ化、選択、および文字クラスを使用することしかできません。正しい IP アドレス: ((2[0-4]d|25[0-5]|[01]?dd?)。){3}(2[0 -4]d|25[0-5]| [01]?dd?)。
この式を理解する鍵は、2[0-4]d|25[0-5]|[ 01]?dd?、行きません
後方参照
括弧を使用して部分式を指定した後、この部分式に一致するテキストを式または他のプログラムでさらに処理できます。デフォルトでは、各グループには自動的にグループ番号が付けられます。ルールは、グループの左括弧をマークとして左から右に始まり、最初のグループのグループ番号は 1、2 番目のグループは 2 です。
後方参照は、前のグループに一致するテキストを繰り返し検索するために使用されます。たとえば、1 はグループ 1 に一致するテキストを表します。
b(w+)bs+1b は、go go、kitty kitty などの繰り返しの単語と一致させるために使用できます。最初の単語は、単語の間にある複数の文字または数字です (b. (w+)b)、次に 1 つ以上の空白文字 (s+)、最後に以前に一致した単語 (1) を作成することもできます。部分式のグループ番号またはグループ名を指定します。部分式のグループ名を指定するには、次の構文を使用してください: (?
表 4. グループ構文キャプチャ
(exp) は exp に一致し、テキストを自動的に名前が付けられたグループにキャプチャします
(?
(?:exp) は exp と一致しますが、一致したテキストはキャプチャしません
位置が指定されています
( ?=exp) は exp の前の位置と一致します
(?<=exp) exp の後の位置と一致します
(?!exp) exp
(? Comment
(?#comment) このタイプのグループは正規表現の処理には影響を与えません。ユーザーが読むためのコメントを提供するだけです
最初の 2 つの構文は次のとおりです。すでに議論されています。 3 番目 (?:exp) は正規表現の処理方法を変更しませんが、そのようなグループに一致するコンテンツは最初の 2 つのようなグループにはキャプチャされません。
場所の指定
次の 4 つは、何かの前後を検索するために使用されます (ただし、これらの内容は含まれません)。つまり、b、^、$ と同じように位置を指定するために使用されるため、ゼロ幅のアサートとも呼ばれます。例を使用して説明するのが最善です。
(?=exp) はゼロ幅先読みアサーションとも呼ばれ、テキスト内の特定の位置に一致し、次の位置は指定されたサフィックス exp に一致します。たとえば、bw+(?=ingb) は、ing で終わる単語の先頭部分 (ing 以外) と一致します。「I'm sing while you're dance.」を検索すると、sing と dance が一致します。
(?<=exp) は、ゼロ幅の改行アサーションとも呼ばれ、exp に一致する指定された接頭辞が前にあるテキスト内の特定の位置に一致します。たとえば、(?<=bre)w+b は、re で始まる単語の後半 (re 以外) に一致します。たとえば、本を読むを検索する場合、ading に一致します。
非常に長い数値の 3 桁ごとにカンマを追加する場合 (もちろん右から追加します)、次のように先頭と内側にカンマを追加する必要がある部分を見つけることができます。 ((( ?<=d)d{3})*b.この式を注意深く分析してください。最初に考えているほど単純ではない可能性があります。
次の例では、プレフィックスとサフィックスの両方を使用しています: (?<=s)d+(?=s) は、空白文字で区切られた数値と一致します (これらの空白文字は含まれません)。
負の位置指定
特定の文字ではない文字、または特定の文字クラス (反意語) に属さない文字を検索する方法については前述しました。しかし、特定の文字が表示されないことを確認したいだけで、その文字と一致させたくない場合はどうすればよいでしょうか?たとえば、文字 q が出現するが、q の後に文字 u が続かない単語を検索したい場合は、これを試すことができます:
bw*q[^u]w*b は、 u ではない文字 q が後に続く単語を含む。しかし、さらにテストを行うと (または、思考が十分に鋭い場合は、それを直接観察できます)、イラク、ベンクのように、単語の末尾に q が現れる場合、この表現は間違っていることがわかります。これは、[^u] は常に 1 つの文字に一致するため、q が単語の最後の文字である場合、次の [^u] は q の後の単語区切り文字 (スペース、ピリオド、その他の文字) に一致するためです。次の w+b は次の単語と一致するため、bw*q[^u]w*b はイラクの戦闘全体と一致します。負の位置指定は 1 つの位置のみに一致し、文字を消費しないため、この問題を解決できます。さて、この問題は次のように解決できます: bw*q(?!u)w*b。
ゼロ幅の負の先読みアサーション (?!exp) は、サフィックス exp が存在しない位置にのみ一致します。 d{3}(?!d) は 3 桁の数字と一致しますが、これら 3 桁の後に数字を続けることはできません。
同様に、(?
より複雑な例: (?<=<(w+)>).*(?=1>) は、属性を含まない単純な HTML タグ内のコンテンツと一致します。 ((w+)>) は接頭辞を指定します。山かっこで囲まれた単語 (たとえば、)、次に .* (任意の文字列)、最後に接尾辞 (? =< ;/1>)。前述の文字エスケープを使用するサフィックスの / に注意してください。1 は後方参照であり、キャプチャされた最初のグループを参照します。そのため、プレフィックスが実際には If 、サフィックスはです。式全体は、 と の間の内容と一致します (ここでもプレフィックスとサフィックス自体は含まれません)。
コメント
括弧のもう 1 つの使用法は、構文 (?#comment) を介してコメントを含めることです。コメントを含める場合は、「パターン内の空白文字を無視する」オプションを有効にするのが最善です。これにより、式を記述するときにスペース、タブ、改行を任意に追加できますが、実際の使用ではこれらは無視されます。このオプションを有効にすると、# に続く行末までのすべてのテキストがコメントとして無視されます。たとえば、前の式を次のように書くことができます:
(?<= # プレフィックスを検索しますが、それは含めません <(w+)> # 山かっこ (タグで囲まれた文字または数字を検索します) ) ) # プレフィックスの終わり* # 任意のテキストと一致します (?= # サフィックスを検索しますが、それは含めません1> # 山かっこで囲まれたコンテンツを検索します: 先頭に「/」があり、その後に以前にキャプチャされたタグが続きます) # サフィックスの終わり
貪欲で怠け者
正規表現に繰り返しを受け入れることができる量指定子 (*、{5,12} などの指定された数のコード) が含まれている場合の通常の動作できるだけ多くの文字に一致することです。次の式を考えてみましょう: a.*b。これは、a で始まり b で終わる最長の文字列と一致します。これを使用して aabab を検索すると、文字列 aabab 全体と一致します。これを貪欲マッチングと呼びます。
場合によっては、遅延マッチング、つまりできるだけ少ない文字のマッチングが必要になることがあります。上記の数量指定子は、後ろに疑問符を追加することで遅延マッチング パターンに変換できます。このように、.*? は、任意の数の繰り返しをマッチングすることを意味しますが、全体のマッチングが成功するよう、最小限の繰り返しを使用します。次に、例の遅延バージョンを見てみましょう:
a.*?b は、a で始まり b で終わる最も短い文字列と一致します。これを aabab に適用すると、aab と ab が一致します。
表 5. 遅延量指定子*? 何度でも繰り返しますが、できるだけ少なくします
+? 1 回以上繰り返しますが、できるだけ少なく繰り返します
??回 n から m 回繰り返しますが、できるだけ少なく繰り返します
{n,m}? n から m 回繰り返しますが、できるだけ少なく繰り返します
{n,} >
他にも何かあります言及されていない
正規表現の構築に必要な多くの要素について説明しましたが、他にも言及していないことがあります。以下に、言及されていない要素のリストを、構文と簡単な説明とともに示します。必要に応じて、より詳細なリファレンスをオンラインで見つけて学習することができます。 MSDN ライブラリをインストールしている場合は、.net で正規表現に関する詳細なドキュメントを見つけることもできます。
表 6. アラーム文字の構文はまだ説明されていません (印刷の効果はコンピューターのビープ音です)
b は通常、単語の境界位置ですが、文字クラスで使用される場合は、バックスペース t タブ文字、タブ
r キャリッジリターン
v 垂直タブ
f ページ送り
n 改行
e エスケープ