JavaRush /Java Blog /Random-JA /RegEx: 正規表現をマスターするための 20 の短いステップ。パート2
Artur
レベル 40
Tallinn

RegEx: 正規表現をマスターするための 20 の短いステップ。パート2

Random-JA グループに公開済み
RegEx: 正規表現をマスターするための 20 の短いステップ。パート 1 原文はこちら 最後のパートでは、最も単純な正規表現をマスターし、すでに何かを学習しました。このパートでは、もう少し複雑なデザインを学習しますが、思っているほど難しくないことを信じてください。 RegEx: 正規表現をマスターするための 20 の短いステップ。 パート 2 - 1それでは、続けてみましょう!

ステップ 8: スター*とプラス記号+

RegEx: 正規表現をマスターするための 20 の短いステップ。 パート 2 - 2これまでのところ、多かれ少なかれ、指定された長さの文字列のみを照合できました。しかし、最新の問題では、これまで見てきた表記法でできることの限界に近づいています。たとえば、3 文字の Java 識別子に限定されず、任意の長さの識別子を使用できると仮定してみましょう。前の例では機能した可能性のある解決策は、次の例では機能しません。
パターン: [a-zA-Z_$]\w\w
文字列:   __e $12 3 3.2 fo Bar r a23 mm ab x
一致: ^^^ ^^^ ^^^ ^^^  
注記つまり、識別子が有効でも 3 文字を超える場合は、最初の 3 文字のみが照合されます。また、識別子が有効であっても、その識別子が 3 文字未満の場合、正規表現はその識別子をまったく見つけられません。問題は、[]などの文字クラスと同様に、括弧で囲まれた式が 1 つの文字にのみ一致することです\w。これは、上記の正規表現内の一致は、正確に 3 文字の長さである必要があることを意味します。したがって、私たちが期待したほどうまく機能しません。*特殊文字と がここで役に立ちます+。これらは、式の右側に追加して、その式に複数回一致させることができる修飾子です。クリーン スター (または「アスタリスク」) は、*前のトークンがゼロ回を含む任意の回数一致する必要があることを示します。プラス記号は、+1 回以上検索する必要があることを示します。したがって、先行する式は+必須 (少なくとも 1 回) ですが、先行する式は*オプションですが、出現する場合は何度でも出現できます。この知識をもとに、上記の正規表現を修正できます。
パターン: [a-zA-Z_$]\w*
文字列:   __e $123 3.2 fo Barr a23mm ab x
一致: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
() ここで、任意の長さの有効な識別子を照合します。ビンゴ!しかし、 ? +の代わりに?を使用するとどうなるでしょうか。*
パターン: [a-zA-Z_$]\w+
文字列:   __e $123 3.2 fo Barr a23mm ab x
一致します: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ 
() 最後の試合、 を欠場しましたх。これは、+少なくとも 1 つの文字が一致する必要があるが、[]先行する括弧で囲まれた式が\w+その文字をすでに「食べている」ためx、使用できる文字がそれ以上ないため、一致は失敗します。いつ使用できますか+? 少なくとも 1 つの一致を見つける必要があるが、指定された式が何回一致する必要があるかは問題ではない場合。たとえば、小数点を含む数値を検索したい場合は次のようになります。
パターン: \d*\.\d+
文字列:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012
一致: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
注記小数点の左側の数値をオプションにすると、0.011 と .2 の両方を見つけることができました。これを行うには、小数点 1 つを と正確に一致させ\.、小数点の右側の少なくとも 1 桁を と一致させる必要がありました\d+。上記の正規表現は、 のような数値には一致しません3.。一致するには、小数点の右側に少なくとも 1 桁の数字が必要だからです。

いつものように、いくつかの簡単な問題を解決してみましょう。

以下の一節の英語の単語をすべて見つけてください。
パターン:
文字列: 3プラス3 は6 ですが、 4プラス 3 は7です
一致します:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
(解決策) 以下のリストですべてのファイル サイズ記号を見つけます。ファイル サイズは、数値 (小数点の有無にかかわらず) とそれに続くKBMBGBまたはで構成されますTB
パターン:
文字列:   11TB 13 14.4MB 22HB 9.9GB TB 0KB
一致: ^^^^ ^^^^^^ ^^^^^ ^^^  
解決

ステップ 9: 「オプション」の疑問符?

RegEx: 正規表現をマスターするための 20 の短いステップ。 パート 2 ~ 3最後の問題を解決するための正規表現をすでに作成しましたか? うまくいきましたか?ここでそれを適用してみてください。
パターン:
文字列: 1..3KB 5...GB ..6TB
一致します:  
明らかに、これらの指定はどちらも有効なファイル サイズではないため、適切な正規表現はどちらにも一致しないはずです。最後の問題を解決するために私が書いた解決策は、少なくとも部分的にはそれらすべてに一致します。
パターン: \d+\.*\d*[KMGT]B
文字列:   1..3KB  5...GB .. 6TB
一致: ^^^^^^ ^^^^^^ ^^^ 
() それで、何が問題なのでしょうか?実際、小数点がある場合は、小数点を 1 つ見つけるだけで済みます。ただし、*ゼロを含む任意の数の一致が許可されます。ゼロ回または 1 回のみ一致させる方法はありますか? しかし、一度だけではだめでしょうか?もちろんあります。「optional」は、?先行する文字の 0 個または 1 つと一致しますが、それ以上の文字には一致しない修飾子です。
パターン: \d+\.?\d*[KMGT]B
文字列: 1.. 3KB 5...GB .. 6TB
一致:     ^^^ ^^^ 
() ここでは解決策に近づいていますが、これは私たちが必要とするものではありません。これをいくつかの手順で修正する方法については、後ほど説明します。

それまでの間、この問題を解決しましょう。

一部のプログラミング言語 (Java など) では、一部の整数および浮動小数点 (ドット) 数値の後にl/Lおよびf/が続きF、通常の int/double ではなく、long/float (それぞれ) として扱われる必要があることを示します。以下の行で有効な「長い」数値をすべて見つけます。
パターン:
文字列:   13L長さ2l 19 L lL 0
一致: ^^^ ^^ ^^ ^ 
解決

ステップ 10: 「または」記号|

RegEx: 正規表現をマスターするための 20 の短いステップ。 パート 2 ~ 4ステップ 8 では、さまざまな種類の浮動小数点数を見つけるのに少し苦労しました。
パターン: \d*\.\d+
文字列:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012
一致: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
上記のパターンは、小数点と小数点の右側に少なくとも 1 桁の数字を照合します。しかし、次のような文字列も一致させたい場合はどうすればよいでしょうか0.? (小数点の右側に数字はありません。) 次のような正規表現を書くことができます。
パターン: \d*\.\d*
文字列:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 
一致: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^ 
() これは に一致します0.が、.上でわかるように 1 つの点にも一致します。実際に照合しようとしているのは、2 つの異なる文字列クラスです。
  1. 小数点の右側に少なくとも 1 桁の数字がある
  2. 小数点の左側に少なくとも 1 桁の数字がある
次の 2 つの正規表現を互いに独立して作成してみましょう。
パターン: \d*\.\d+
文字列:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
一致: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
パターン: \d+\.\d*
文字列:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
一致: ^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^^^ 
42これらのいずれの場合でも、部分文字列、56または が.エンジンによって検出されないこと がわかります。必要な結果を得るには、これらの正規表現を組み合わせても問題ありません。どうすればこれを達成できるでしょうか? 「or」記号を使用すると、|正規表現で一度に複数の一致シーケンスを指定できます。[]「or」記号を使用して代替の単一文字を指定できるのと同じように、|代替の複数文字の式を指定できます。たとえば、「犬」または「猫」を検索したい場合は、次のように記述できます。
パターン: \w\w\w
文字列:  明らかに犬はよりも優れたペットです。
一致: ^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^ 
() ... ただし、これはクラス "word" のすべての 3 文字シーケンスに一致します。ただし、「犬」と「猫」には共通の文字さえないため、ここでは角括弧は役に立ちません。これら 2 つの単語の両方に一致する、またはこれら 2 つの単語のみに一致する、使用できる最も単純な正規表現を次に示します。
パターン:犬|猫
文字列: 明らかに、犬はよりも優れたペットです。
一致:               ^^^ ^^^ 
() 正規表現エンジンは、最初に文字の左側のシーケンス全体の照合を試みます|が、失敗した場合は、文字の右側のシーケンスの照合を試みます|。複数の文字を|連鎖させて、3 つ以上の代替シーケンスと一致させることもできます。
パターン:犬|猫|ペット
文字列: 明らかに、犬はよりも優れたペットです。
一致:               ^^^ ^^^ ^^^ 

ここで、このステップをよりよく理解するために、別のいくつかの問題を解決してみましょう。

記号を使用して|上記の 10 進正規表現を修正すると、次のような結果が得られます。
パターン:
文字列:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
一致: ^^^^^ ^^ ^^^^^^^ ^^^^^ ^^^^^^^^^ 
(解決策) 前のステップの最後の問題で説明したように、sign |、文字クラス、 "optional"?などを使用して、整数と浮動小数点数 (ドット) の両方に一致する単一の正規表現を作成します (この問題は少し複雑です)もっと複雑です、はい ;))
パターン:
文字列:   42L 12 x 3.4f 6l 3.3 0F LF .2F 0.
一致: ^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^  
(解決策) 正規表現をマスターするための 20 の短いステップ。パート 3 RegEx: 正規表現をマスターするための 20 の短いステップ。パート 4
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION