正規(guī)表現(xiàn)の概要と構文
なぜ正規(guī)表現(xiàn)を使用するのですか?
一般的な検索と置換の操作では、予想される検索結果と一致する正確なテキストを提供する必要があります。この手法は、靜的テキストに対して単純な検索および置換タスクを実行するには十分かもしれませんが、柔軟性に欠けているため、この方法では動的テキストの検索が不可能ではないにしても困難になります。
正規(guī)表現(xiàn)を使用すると、次のことが可能になります。
1. 文字列內のパターンをテストします。
たとえば、入力文字列をテストして、文字列內に電話番號パターンまたはクレジット カード番號パターンが出現(xiàn)するかどうかを確認できます。これはデータ検証と呼ばれます。
2. テキストを置き換えます。
正規(guī)表現(xiàn)を使用すると、ドキュメント內の特定のテキストを識別したり、そのテキストを完全に削除したり、他のテキストに置き換えたりすることができます。
3. パターンマッチングに基づいて文字列から部分文字列を抽出します。
文書または入力フィールド內で特定のテキストを検索できます。
たとえば、サイト全體を検索し、古いコンテンツを削除し、特定の HTML 書式設定タグを置き換える必要がある場合があります。この場合、正規(guī)表現(xiàn)を使用して、このマテリアルまたはこの HTML 書式設定タグが各ファイルに存在するかどうかを判斷できます。このプロセスにより、影響を受けるファイルのリストが、削除または変更が必要な內容を含むファイルに絞り込まれます。正規(guī)表現(xiàn)を使用して、古い內容を削除できます。最後に、正規(guī)表現(xiàn)を使用してタグを検索および置換できます。
正規(guī)表現(xiàn) - 構文
正規(guī)表現(xiàn) (正規(guī)表現(xiàn)) は、文字列に特定の部分文字列が含まれているかどうかを確認したり、一致する部分文字列を置き換えたり、特定の文字列から選択したりするために使用できる文字列一致パターンを記述します。條件など
ディレクトリをリストする場合、dir *.txt または ls *.txt 內の *.txt は正規(guī)表現(xiàn)ではありません。これは、ここでの * の意味が正規(guī)表現(xiàn)の * とは異なるためです。
正規(guī)表現(xiàn)の構築は、數(shù)式の作成と同じです。つまり、さまざまなメタ文字や演算子を使用して、小さな式を組み合わせて、より大きな式を作成できます。正規(guī)表現(xiàn)のコンポーネントは、単一の文字、文字のコレクション、文字の範囲、文字間の選択、またはこれらすべてのコンポーネントの任意の組み合わせにすることができます。
正規(guī)表現(xiàn)は、通常の文字 (文字 a ~ z など) と特殊文字 (「メタ文字」と呼ばれる) で構成されるテキスト パターンです。パターンは、テキストを検索するときに一致する 1 つ以上の文字列を記述します。正規(guī)表現(xiàn)は、文字パターンと検索文字列を照合するテンプレートとして機能します。
通常の文字
通常の文字には、メタキャラクターとして明示的に指定されていないすべての印刷可能文字と印刷不可能な文字が含まれます。これには、すべての大文字と小文字、すべての數(shù)字、すべての句読點、およびその他の記號が含まれます。
非印刷文字
非印刷文字も正規(guī)表現(xiàn)の一部にすることができます。次の表に、非印刷文字を表すエスケープ シーケンスを示します。
Character Description
cx x で指定された制御文字と一致します。たとえば、cM は Control-M または復帰文字と一致します。 x の値は、A ~ Z または a ~ z のいずれかでなければなりません。それ以外の場合、c はリテラルの「c」文字として扱われます。
f フォーム フィードと一致します。 x0c および cL に相當します。
n は改行文字と一致します。 x0a および cJ に相當します。
r 復帰文字と一致します。 x0d および cM に相當します。
s スペース、タブ、フォーム フィードなどを含む任意の空白文字と一致します。 【fnrtv】に相當。
S は空白以外の文字に一致します。 [^ fnrtv] に相當します。
タブ文字と一致しません。 x09 および cI に相當します。
v は垂直タブ文字と一致します。 x0b および cK に相當します。
特殊文字
いわゆる特殊文字は、上記の「*.txt」の * のように、単に任意の文字列の意味を意味する、特別な意味を持つ文字です。ファイル名に * が含まれるファイルを検索する場合は、* をエスケープする、つまり * の前に 1 を追加する必要があります。 ls *.txt。
多くのメタキャラクターは、それらを照合するときに特別な処理が必要です。これらの特殊文字と一致させるには、まず文字を「エスケープ」する必要があります。つまり、文字の前にバックスラッシュ文字 () を付けます。次の表に、正規(guī)表現(xiàn)の特殊文字を示します。
特殊文字 説明
$ 入力文字列の終了位置と一致します。 RegExp オブジェクトの Multiline プロパティが設定されている場合、$ は 'n' または 'r' にも一致します。 $ 文字そのものと一致させるには、$ を使用します。
( ) 部分式の開始と終了をマークします。部分式は後で使用するために取得できます。これらの文字と一致させるには、( と ) を使用します。
* 直前の部分式と 0 回以上一致します。 * 文字と一致させるには、* を使用します。
+ 前の部分式と 1 回以上一致します。 + 文字と一致させるには、+ を使用します。
。改行文字 n を除く任意の 1 文字と一致します。 . と一致させるには、 を使用します。
[ 角括弧式の始まりを示します。 [ と一致させるには、[ を使用します。
? 先行する部分式に 0 回または 1 回一致するか、非貪??欲修飾子を指定します。 ? 文字に一致させるには、? を使用します。
次の文字を特殊文字、リテラル文字、後方參照、または 8 進エスケープ文字としてマークします。たとえば、「n」は文字「n」と一致します。 「n」は改行文字に一致します。シーケンス '\' は "" と一致し、'(' は "(" と一致します。
^ 角括弧式で使用されない限り、入力文字列の先頭と一致します。角括弧式で使用されている場合、文字セットが受け入れられないことを示します。 ^ 文字自體に一致するには、^ を使用します。{ に一致するには、{ を使用します。
修飾子正規(guī)表現(xiàn)の指定されたコンポーネントは、* または + または ? または {n} または {n,} または {n,m} の合計で 6 種類存在します。正規(guī)表現(xiàn)は次のとおりです: 文字
説明* 前の部分式と 0 回以上一致します。たとえば、zo* は "z" および ".zoo" と一致します。* は {0, と同等です。 }. + 前の部分式と 1 回以上一致します。たとえば、「zo+」は「zo」と一致しますが、「z」は一致しません。たとえば、前の部分式は 0 回または 1 回、{0,1} の "do" または "does" と一致します。整數(shù)。たとえば、「o{2}」は「Bob」の「o」と一致しますが、「food」の 2 つの「o」は一致します。
{n,} n は負ではない整數(shù)です。少なくとも n 回一致します。たとえば、「o{2,}」は「Bob」の「o」とは一致しませんが、「foooood」のすべての「o」と一致します。 「o{1,}」は「o+」と同等です。 「o{0,}」は「o*」と同等です。
{n,m} m と n は両方とも非負の整數(shù)であり、n <= m です。少なくとも n 回、最大で m 回一致します。たとえば、「o{1,3}」は「fooooood」の最初の 3 つの o と一致します。 「o{0,1}」は「o?」と同等です。カンマと 2 つの數(shù)字の間にスペースを入れることはできないことに注意してください。
大きな入力ドキュメントでは章番號が 9 を超える可能性があるため、2 桁または 3 桁の章番號を処理する方法が必要です。修飾子はこの能力を與えます。次の正規(guī)表現(xiàn)は、任意の桁數(shù)で番號付けされた章タイトルに一致します:
/Chapter [1-9][0-9]*/
範囲式の後に修飾子が表示されることに注意してください。したがって、これは範囲式全體に適用されます。この場合、0 ~ 9 (両端の値を含む) の數(shù)値のみが指定されます。
2 番目以降の位置に必ずしも數(shù)字を入れる必要がないため、ここでは + 修飾子は使用されません。それも使わないの?章番號が 2 桁に制限されているためです。章の後に少なくとも 1 つの數(shù)字とスペース文字が一致する必要があります。
章番號が 99 章のみに制限されていることがわかっている場合は、以下の式を使用して少なくとも 1 桁、最大 2 桁を指定できます。
/Chapter [0-9]{1,2}/
上記の式の欠點は、99 より大きい章番號が最初の 2 桁にしか一致しないことです。もう一つの欠點は、Chapter 0 も一致することです。 2 桁のみを照合するより適切な表現(xiàn)は次のようになります:
/Chapter [1-9][0-9]?/
または
/Chapter [1-9][0-9] The { 0,1}/
*、+、および ? 修飾子は、後ろに ? を追加することで可能な限り多くのリテラルと一致するため、すべて貪欲です。
たとえば、HTML ドキュメント內で H1 タグで囲まれた章のタイトルを検索するとします。文書內のテキストは次のようになります:
<H1>第 1 章 – 正規(guī)表現(xiàn)の概要</H1>
次の式は、開始の不等號 (<) から終了 H1 タグまで一致します。より大きい記號 (>)。
/<.*>/
開始 H1 タグのみを一致させる必要がある場合、以下の「非貪欲」式は <H1> のみに一致します。
/<.*?>/
*、+、または ? 修飾子の後に ? を置くと、式は「貪欲な」式から「非貪欲な」式または最小一致に変換されます。
ロケーター
ロケーターを使用すると、正規(guī)表現(xiàn)を行の先頭または末尾に固定できます。また、単語內、単語の先頭、または単語の末尾に表示される正規(guī)表現(xiàn)を作成することもできます。
ロケーターは文字列または単語の境界を表すために使用され、^ と $ はそれぞれ文字列の先頭と末尾を指し、b は単語の前または後ろの境界を表し、B は単語以外の境界を表します。 。
正規(guī)表現(xiàn)の修飾子は次のとおりです:
Character Description
^ 入力文字列の先頭と一致します。 RegExp オブジェクトの Multiline プロパティが設定されている場合、^ は n または r の後の位置にも一致します。
$ 入力文字列の末尾と一致します。 RegExp オブジェクトの Multiline プロパティが設定されている場合、$ は n または r の前の位置にも一致します。
b 単語の境界、つまり単語とスペースの間の位置に一致します。
B 非単語境界のマッチング。
注: アンカー ポイントを含む修飾子は使用できません。改行または単語境界の直前または直後に複數(shù)の位置を置くことはできないため、^* などの表現(xiàn)は許可されません。
テキスト行の先頭のテキストを照合するには、正規(guī)表現(xiàn)の先頭に ^ 文字を使用します。この ^ の使用と括弧內の式の使用を混同しないでください。
テキスト行の末尾のテキストと一致するには、正規(guī)表現(xiàn)の末尾に $ 文字を使用します。
章のタイトルを検索するときにアンカー ポイントを使用するには、次の正規(guī)表現(xiàn)は、末尾に 2 桁のみを含み、行の先頭に表示される章のタイトルと一致します:
/^Chapter [1-9][ 0-9 ]{0,1}/
実際の章のタイトルは行の先頭に表示されるだけでなく、行內の唯一のテキストでもあります。これは、行の先頭と同じ行の末尾の両方に表示されます。次の式は、指定された一致が相互參照ではなく章のみに一致することを保証します。これを行うには、テキスト行の先頭と末尾のみに一致する正規(guī)表現(xiàn)を作成します。
/^Chapter [1-9][0-9]{0,1}$/
は、単語の境界を若干異なる方法で照合しますが、正規(guī)表現(xiàn)に重要な機能を追加します。単語の境界は、単語とスペースの間の位置です。非単語境界は、その他の位置です。次の式は、Chapter という単語の最初の 3 文字と一致します。これらの 3 文字は単語境界の後に出現(xiàn)するためです:
/bCha/
b 文字の位置は非常に重要です。単語の先頭が一致する文字列の先頭にある場合は、その単語の先頭で一致するものを探します。それが文字列の末尾にある場合は、単語の末尾で一致するものを探します。たとえば、次の式は、単語 Chapter の文字列 ter と一致します。これは単語境界の前にあるためです。
/terb/
次の式は、Chapter の文字列 apt と一致しますが、apt の aptitude 文字列とは一致しません。
/バプト/
文字列 apt は、単語 Chapter では単語以外の境界で発生しますが、単語 aptitude では単語境界で発生します。 B 非単語境界演算子の場合、単語の先頭か末尾が一致するかどうかは関係ないため、位置は重要ではありません。
Select
すべての選択をかっこで囲み、隣接する選択を | で區(qū)切ります。ただし、括弧を使用すると、関連する一致がキャッシュされるという副作用が生じます。この場合、最初のオプションの前に ?: を使用すると、この副作用を排除できます。
このうち、?: は非キャプチャー要素の 1 つで、他の 2 つの非キャプチャー要素は ?= と ?! です。これら 2 つは前方參照であり、括弧內にあるものと一致します。後者は、正規(guī)表現(xiàn)パターンに一致しない任意の位置の検索文字列に一致します。
後方參照
正規(guī)表現(xiàn)パターンまたはパターンの一部をかっこで囲むと、関連付けられた一致が一時バッファーに保存され、キャプチャされた各部分一致が正規(guī)表現(xiàn)パターンと同様にキャプチャされます。外観は左から右へ。バッファの番號付けは 1 から始まり、最大 99 個のキャプチャされた部分式を保存できます。各バッファーには、「n」を使用してアクセスできます。n は、特定のバッファーを識別する 1 桁または 2 桁の 10 進數(shù)です。
キャプチャは、関連付けられた一致の保存を無視して、非キャプチャ メタキャラクタ「?:」、「?=」、または「?!」を使用してオーバーライドできます。
後方參照の最もシンプルで便利なアプリケーションの 1 つは、テキスト內で隣接する 2 つの同一の単語の一致を見つける機能です。次の文を例に挙げます:
ガソリンのコストは上がりますか?
上の文には明らかに複數(shù)の単語が繰り返されています。各単語の繰り返しを探すことなく、この文を見つける方法を工夫するとよいでしょう。次の正規(guī)表現(xiàn)は、単一の部分式を使用してこれを実現(xiàn)します。
/b([a-z]+) 1b/gi
は、[a-z]+ で指定された、1 つ以上の文字を含む式をキャプチャします。正規(guī)表現(xiàn)の 2 番目の部分は、以前に取得された部分一致への參照、つまり、括弧表現(xiàn)と完全に一致する?yún)g語の 2 番目の出現(xiàn)です。 1 は最初のサブマッチを指定します。単語境界メタキャラクターにより、単語全體のみが確実に検出されます。そうしないと、「発行されました」や「これは」などの語句がこの式で正しく認識されません。
正規(guī)表現(xiàn)の後のグローバル タグ (g) は、入力文字列內で見つかったすべての一致にその式が適用されることを示します。式の末尾にある case-insensitive (i) タグは、大文字と小文字を區(qū)別しないことを指定します。複數(shù)行タグは、改行文字のどちらかの側で発生する可能性のある一致を指定します。
後方參照は、Universal Resource Indicator (URI) をそのコンポーネントに分割することもできます。次の URI をプロトコル (ftp、http など)、ドメイン アドレス、およびページ/パスに分割するとします:
http://www.w3cschool.cc:80/html/html-tutorial.html
以下の正規(guī)表現(xiàn)はこの機能を提供します:
/(w+)://([^/:]+)(:d*)?([^# ]*)/
最初の括弧部分式は、Web アドレスのプロトコル部分をキャプチャします。この部分式は、コロンと 2 つのスラッシュが前にある任意の単語と一致します。 2 番目の括弧部分式は、アドレスのドメイン アドレス部分を取得します。部分式は、/ と : を除く 1 つ以上の文字と一致します。 3 番目の括弧內の部分式は、ポート番號 (指定されている場合) を取得します。この部分式は、コロンに続く 0 個以上の數(shù)字と一致します。この部分式は 1 回だけ繰り返すことができます。最後に、括弧で囲まれた 4 番目の部分式は、Web アドレスで指定されたパスおよび/またはページ情報を取得します。この部分式は、# またはスペース文字を含まない任意の文字シーケンスと一致します。
上記の URI に正規(guī)表現(xiàn)を適用すると、各部分一致には以下が含まれます:
1) 最初の括弧で囲まれた部分式には「http」が含まれます
2) 2 番目の括弧で囲まれた部分式には「www .w3cschool.cc」が含まれます
3) 3 番目の括弧の部分表現(xiàn)には「:80」が含まれています
4) 4 番目の括弧の部分表現(xiàn)には「../html/html-tutorial.html」が含まれています
atom
アトムは、正規(guī)表現(xiàn)の最小単位です。アトムは一致する必要があるコンテンツです。有効な正規(guī)表現(xiàn)には、少なくとも 1 つのアトムが含まれている必要があります。
説明: 私たちが目にするスペース、復帰、改行、0 ~ 9、A-Za-Z、中國語、句読點、特殊記號はすべてアトムです。
アトミックな例を行う前に、まず関數(shù) preg_match:
int preg_match (string $ Regular, string $string[, array &$result]) について説明しましょう
関數(shù): $regulator 変數(shù) $string に従って照合します変數(shù)。存在する場合は、一致の數(shù)を返し、一致した結果を $result 変數(shù)に入れます。結果が見つからない場合は 0 が返されます。
開始と終了
^は開始を意味し、$は終了を意味します
次のコードはdateで始まる任意の數(shù)値と一致します
$str = 'date20150121';
echo '一致成功';
} else {
echo '一致失敗';
}
w は、文字、數(shù)字、またはアンダースコア文字の一致に使用されます。
d は、 を表す數(shù)値 (D は非數(shù)値を意味します) と一致します
$str = 'date20150121';
if (preg_match('/^w/', $str, $matches)) {
print_r($matches);
} else {
echo 'Match failed';
}
特別に識別された原子
Atom 説明
d 0-9 と一致します
D 0-9 を除くすべての文字
w a-zA-Z0-9_
W 0-9A-Za-z を除くすべての文字_
s スペースのすべての空白文字と一致します
S 空白以外のすべての文字と一致します
[ ] アトムの範囲を指定します
例:
d は 0 ~ 9 に一致します
<?php
$zz = '/\d/';
$string = '我愛喝9你愛不愛喝';
if(preg_match($zz, $string, $matches)){
echo '匹配到了,結果為:';
var_dump($matches);
}else{
echo '沒有匹配到';
}
?>
D は 0-9 以外の値と一致します
<?php $zz = '/\D/'; $string = '121243中23453453'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>照合は成功し、試合に入ります。 0 ~ 9 の文字ではないためです。
w は a-zA-Z0-9_
<?php $zz = '/\w/'; $string = '新中_國萬歲呀萬歲'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>と一致します 一致は成功し、アンダースコアが一致します。
W は非 a-zA-Z0-9_
<?php $zz = '/\w/'; $string = 'afasABCWEQR44231284737'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>と一致しましたが失敗しました。なぜなら、上記はすべて a-zA-Z0-9_ であり、a-zA-Z0-9_ でないものは何もないからです。
s は、スペース以外のすべての空白文字と一致します。
<?php $zz = '/\s/'; $string = "中國萬 歲"; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>復帰があるため、一致は成功します。
S の空でない文字
<?php $zz = '/\s/'; $string = " a "; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>が正常に一致しました。スペースはありますが、改行とインデントが表示されます。ただし、空白以外の文字 a が存在します。したがって、試合は成功です。
[] は原子の範囲を指定します
<?php $zz = '/[0-5]\w+/'; $string = '6a'; $string1 = '1C'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>結論: 上記の例では、0-5 は $string と一致しませんでしたが、$string1 は成功しました。 $string の最初の値は 6 であり、[0-5] の範囲內にないためです。
<?php $zz = '/[a-zA-Z0-9_]\w/'; $string = 'ab'; $string1 = '9A'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>
結論:
<?php $zz = '/[abc]\d+/'; $string = 'a9'; $string1 = 'b1'; $string2 = 'c5'; $string3 = 'd4'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>結論:$string、$string1、$string2 は正常に一致しますが、$string3 は一致しません。 $string3は[abc]の範囲を超えているため、dから始まります。
[^ 文字] は指定された範囲の文字と一致しません
<?php $zz = '/[^0-9A-Za-z_]/'; $string = 'aaaaab311dd'; $string1 = '!$@!#%$#^##'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,結果為:'; var_dump($matches); }else{ echo '沒有匹配到'; } ?>結論:
1) $string のマッチングは失敗しましたが、$string1 のマッチングは成功しました。角括弧內にサーカムフレックス文字があるためです。
2) 角括弧內の ^ サーカムフレックス文字の機能は、角括弧內の文字と一致することではありません。