Rubyの正規表現をマスターする
Rubyの正規表現( Ruby regex 略して)さらに処理するためにデータを抽出する目的で、文字列内の特定のパターンを見つけるのに役立ちます。
正規表現の2つの一般的な使用例には、検証と解析が含まれます。
例 :
ruby正規表現を含むメールアドレスについて考えてみてください 有効な電子メールアドレスがどのように見えるかを定義できます。つまり、プログラムは有効なメールアドレスと無効なメールアドレスを区別できるようになります。
Rubyの正規表現は2つのスラッシュの間に定義されます それらを他の言語構文と区別するため。最も単純な表現は、単語または1文字にさえ一致します。
例 :
# Find the word 'like' "Do you like cats?" =~ /like/
これは、単語が見つかった場合(一致が成功した場合)またはnil
の場合に、単語の最初の出現のインデックスを返します。 それ以外は。インデックスを気にしない場合は、String#includeを使用できますか?メソッド。
文字列が正規表現と一致するかどうかを確認する別の方法は、match
を使用することです。 方法:
if "Do you like cats?".match(/like/) puts "Match found!" end
今:
日付、電話番号、メール、URLなどを照合、キャプチャ、置換できるように、より高度なパターンを構築する方法を学習します。
キャラクタークラス
文字クラスを使用すると、一致する文字の範囲またはリストを定義できます。例:[aeiou]
任意の母音に一致します。
例 :文字列は含む 母音?
def contains_vowel(str) str =~ /[aeiou]/ end contains_vowel("test") # returns 1 contains_vowel("sky") # returns nil
これは金額を考慮しません キャラクターの数については、すぐにそれを行う方法を見ていきます。
範囲
範囲を使用して、すべてを入力しなくても、複数の文字や数字を照合できます。つまり、[2-5]
のような範囲 [2345]
と同じです 。
いくつかの有用な範囲:
- [0-9] 0から9までの任意の数値に一致します
- [a-z] aからzまでの任意の文字に一致します(キャップなし)
- [^ a-z] 否定された範囲
例 :この文字列には数字が含まれていますか?
def contains_number(str) str =~ /[0-9]/ end contains_number("The year is 2015") # returns 12 contains_number("The cat is black") # returns nil
注意: `=〜`を使用した場合の戻り値は、文字列インデックスまたは `nil`
のいずれかです。
文字範囲を指定するための優れた省略構文があります:
- \ w [0-9a-zA-Z_]と同等です
- \ d [0-9]と同じです
- \ s 空白に一致します (タブ、通常のスペース、改行)
これらの否定的な形もあります:
- \ W [0-9a-zA-Z_]にないもの
- \ D 数字ではないもの
- \ S スペース以外のもの
ドット文字.
新しい行以外のすべてに一致します。リテラルの.
を使用する必要がある場合 その後、それを脱出する必要があります。
例 :特殊文字のエスケープ
# If we don't escape, the letter will match "5a5".match(/\d.\d/) # In this case only the literal dot matches "5a5".match(/\d\.\d/) # nil "5.5".match(/\d\.\d/) # match
修飾子
これまで、一度に1つの文字しか一致させることができませんでした。複数の文字を一致させるために、パターン修飾子を使用できます。
+ | 1つ以上 |
* | 0以上 |
? | 0または1 |
{3,5} | 3から5の間 |
これまでに学んだことをすべて組み合わせて、より複雑な正規表現を作成できます。
例 :これはIPアドレスのように見えますか?
# Note that this will also match some invalid IP address # like 999.999.999.999, but in this case we just care about the format. def ip_address?(str) # We use !! to convert the return value to a boolean !!(str =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) end ip_address?("192.168.1.1") # returns true ip_address?("0000.0000") # returns false
完全な文字列照合
完全一致が必要な場合は、別のタイプの修飾子が必要になります。私が話していることを確認できるように、例を見てみましょう:
# We want to find if this string is exactly four letters long, this will # still match because it has more than four, but it's not what we want. "Regex are cool".match /\w{4}/ # Instead we will use the 'beginning of line' and 'end of line' modifiers "Regex are cool".match /^\w{4}$/ # This time it won't match. This is a rather contrived example, since we could just # have used .size to find the length, but I think it gets the idea across.
すべての行だけでなく、文字列の先頭で厳密に一致させる(\n
の後) )\A
を使用する必要があります および\Z
^
の代わりに および$
。
キャプチャグループ
キャプチャグループを使用すると、一致の一部をキャプチャして後で再利用できます。一致をキャプチャするために、キャプチャする部分を括弧で囲みます。
例 :ログファイルの解析
Line = Struct.new(:time, :type, :msg) LOG_FORMAT = /(\d{2}:\d{2}) (\w+) (.*)/ def parse_line(line) line.match(LOG_FORMAT) { |m| Line.new(*m.captures) } end parse_line("12:41 INFO User has logged in.") # This produces objects like this: #
この例では、.match
を使用しています =~
の代わりに 。
このメソッドはMatchData
を返します 一致する場合はオブジェクト、それ以外の場合はnil。 MatchData
クラスには多くの便利なメソッドがあります。詳細については、ドキュメントを確認してください!
ブール値のみが必要な場合(true
/ false
)次に、match?
を使用できます Ruby2.4以降で使用可能なメソッド。これもmatch
よりも高速です RubyはMatchData
を作成する必要がないため オブジェクト。
.captures
を使用してキャプチャされたデータにアクセスできます メソッドまたはMatchData
の処理 配列のようなオブジェクトの場合、ゼロインデックスは完全に一致し、結果のインデックスには一致したグループが含まれます。
最初のキャプチャグループが必要な場合は、次のように実行できます。
m = "John 31".match /\w+ (\d+)/ m[1] # 31
キャプチャしないグループを持つこともできます。パフォーマンスを低下させることなく、式をグループ化できます。複雑な表現を読みやすくするために、名前付きグループが役立つ場合もあります。
(?:...) |
(?<foo>...) |
例 :名前付きグループ
m = "David 30".match /(?\w+) (?\d+)/ m[:age] # => "30" m[:name] # => "David"
名前付きグループはMatchData
を返します 結果を読み取るためにアクセスできるオブジェクト。
先を見て後ろを見る
これは、すべての正規表現の実装で利用できるとは限らない、より高度な手法です。 Rubyの正規表現エンジンはこれを実行できるので、それを利用する方法を見てみましょう。
先を見越して、前後に特定の一致があるかどうかを確認できます。
(?=pat) |
(?<=pat) |
(?! pat) |
(?<!pat) |
例 :少なくとも1文字の前に数字がありますか?
def number_after_word?(str) !!(str =~ /(?<=\w) (\d+)/) end number_after_word?("Grade 99")
ルビーの正規表現クラス
Rubyの正規表現は、Regexp
のインスタンスです。 クラス。ほとんどの場合、このクラスを直接使用することはありませんが、知っておくとよいでしょう🙂
puts /a/.class # Regexp
考えられる用途の1つは、文字列から正規表現を作成することです。
regexp = Regexp.new("a")
正規表現を作成する別の方法:
regexp = %r{\w+}
正規表現オプション
正規表現にいくつかのオプションを設定して、動作を変えることができます。
オプション | 説明 |
---|---|
i | ruby正規表現の大文字と小文字を区別しない |
m | ドットは改行と一致します |
x | 空白を無視する |
これらのオプションを使用するには、正規表現の最後の/
を閉じる後に文字を追加します 。
このように :
"abc".match?(/[A-Z]/i)
長い正規表現のフォーマット
複雑なRuby正規表現はかなり読みにくくなる可能性があるため、複数行に分割すると便利です。これは、「x」修飾子を使用して行うことができます。この形式では、正規表現内でコメントを使用することもできます。
例 :
LOG_FORMAT = %r{ (\d{2}:\d{2}) # Time \s(\w+) # Event type \s(.*) # Message }x
Rubyの正規表現:すべてをまとめる
正規表現は多くのRubyメソッドで使用できます。
- .split
- .scan
- .gsub
- その他多数…
例 :.scan
を使用して文字列のすべての単語を照合します"this is some string".scan(/\w+/) # => ["this", "is", "some", "string"]
例 :文字列からすべての数値を抽出します
"The year was 1492.".scan(/\d+/) # => ["1492"]
例 :文字列内のすべての単語を大文字にします
str = "lord of the rings" str.gsub(/\w+/) { |w| w.capitalize } # => "Lord Of The Rings"
例 :メールアドレスを検証する
email = "[email protected]" !!email.match(/\A[\w.+-]+@\w+\.\w+\z/) # true
この最後の例では、!!
を使用しています 結果をブール値に変換します(true
/ false
)、または、match?
を使用することもできます Ruby 2.4+のメソッドは、すでにこれを実行しており、さらに高速です。
結論
正規表現は素晴らしいですが、少し注意が必要な場合もあります。 rubular.comなどのツールを使用すると、ruby正規表現を作成するのに役立ちます よりインタラクティブな方法で。 Rubularには、非常に便利なRuby正規表現のチートシートも含まれています。今度は、そのエディターを開いてコーディングを開始する番です!
ああ、これを共有することを忘れないでください 楽しんだら友達と一緒に、もっと多くの人が学べるように🙂
-
JavaScript正規表現
正規表現は、検索パターンを説明する文字列です。この検索パターンは、テキストで検索する内容を指定するために使用されます。 以下はJavaScriptの正規表現のコードです- 例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <
-
アサーションの背後にあるJavaScript正規表現
Lookbehindでは、前に何かがある場合にのみパターンを一致させることができます。以下は例です- 例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <