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 = "test@example.com" !!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> <