ときどき正規表現を見ても、それをマスターすることを敢えてしないなら、これはすべて信じられないほど難しいと思います-あなたは知っています-あなたは一人ではありません。 正規表現が何であるかを理解していない人、またはそれらがどのように機能するかを理解していない人にとって、彼らは完全なナンセンスのように見えます。
注意を引くための強力な画像:)注意、それは吸うことができます!しかし、実際には、正規表現は膨大な時間を節約するのに役立つ強力なツールです。 この記事では、JavaScriptの正規表現の基本について説明します。
JSでの正規表現の作成
JavaScriptでは、正規表現は文字列内の文字の組み合わせを検索するために使用されるオブジェクトの一種です。
正規表現を作成するには2つの方法があります。
1つは、正規表現リテラルを使用することです。 このアプローチでは、正規表現パターンはスラッシュで囲まれます。 次のようになります。
var regexLiteral = /cat/;
2番目は
RegExpオブジェクトのコンストラクターを使用し、正規表現の作成元の文字列を受け取ります。
var regexConstructor = new RegExp("cat");
上記の両方の例で、同じテンプレートが作成され
c記号、
c記号、
t記号の順になります。
選択する正規表現を作成する方法は? ここでは、このルールを順守する必要があります。正規表現を使用して変更しないようにする場合は、リテラルを使用することをお勧めします。 正規表現が動的な場合、プログラムの実行中に変化する可能性があるため、
RegExpコンストラクターを使用することをお
RegExpます。
正規表現の方法
JSの正規表現はオブジェクトであることに気づいたかもしれません。 オブジェクトにはメソッドがあることが知られており、正規表現も例外ではありません。
主な正規表現メソッドの1つは、ブール値を返す
.test()です。
RegExp.prototype.test()
つまり、文字列に指定された正規表現パターンとの一致が含まれている場合、このメソッドは
true返し
true 。 一致するものが見つからない場合、
false返し
false 。
次の例を考えてみましょう。 2行と1つの正規表現があります。 正規表現を使用して、特定のテキストパターンが文字列で発生するかどうかを確認できます。
const str1 = "the cat says meow"; const str2 = "the dog says bark"; const hasCat = /cat/; hasCat.test(str1);
予想どおり、最初の行
str1を調べて、その中に
cat文字のシーケンスがあるかどうかを確認すると、
trueになり
true 。 しかし、2行目の
str2チェックした後、その中に
catが見つからないため、
.test()メソッドは
false返し
false 。
基本的な正規表現の構成
幸いなことに(または不幸なことに、これは他の誰かです)、正規表現の研究への主なアプローチは、シンボルとシンボルのグループを示す基本構造を覚えることです。
基本的な正規表現の構成要素の短いリストを次に示します。 それらを研究することに真剣に取り組んでいるなら、これらの構成を学ぶために20分ほどかかります。
▍記号
. (ピリオド)-改行を除く任意の1文字に一致します。
* -0回以上繰り返される前の表現と一致します。
+ -1回以上繰り返される前の表現に一致します。
? -0回または1回繰り返される前の表現に一致します。
^ -行の先頭に一致します。
$ -行末に一致します。
▍キャラクターグループ
\d任意の1つの数字と一致します。
\w任意の文字(数字、文字、または下線)に一致します。
[XYZ] -文字のセット。 大括弧で指定されたセットの任意の1文字に一致します。 さらに、たとえば[AZ]ように、文字範囲を同様の方法で指定できます。
[XYZ]+回以上繰り返された括弧の文字に一致します。
[^AZ] -文字の範囲を指定する式の内部では、 ^文字は否定記号として使用されます。 この例では、パターンは大文字以外のすべてに一致します。
▍フラグ
5つのオプションの正規表現フラグがあります。 これらは一緒に使用することも個別に使用することもできます。終了スラッシュの後に配置されます。 フラグ付きの正規表現は次のようになります:
/[AZ]/g ここでは、2つのフラグのみを検討します。
gグローバル文字列検索。
i大文字と小文字を区別しない検索。
▍追加のデザイン
(x) -ブラケットのキャプチャ。 この式はx一致し、この一致を記憶するため、後で使用できます。
(?:x) -非キャプチャーブラケット。 式はxに一致しますが、この一致を覚えていません
x(?=y)はプリエンプティブマッチです。 y後に続く場合にのみx一致します。
正規表現のより複雑な例
トレーニングプロジェクトを開始する前に、今調査した内容の実際の使用について詳しく説明します。
まず、行の数字を確認します。 これを行うには、
\dパターンを使用できます。 以下のコードをご覧ください。 調査中の文字列に少なくとも1つの数字が
true場合、
true返し
true 。
console.log(/\d/.test('12-34'));
ご覧のとおり、コードは
true返し
true 。調査中の行には4つの数字があるため、これは驚くことではありません。
しかし、文字列にデジタル文字の特定のシーケンスが存在するかどうかを確認する必要がある場合はどうでしょうか? この場合、
\dパターンを数回使用できます。 たとえば、正規表現を
11行目に一致させるには、
\d\d構成体を使用できます。これは、2つの数字を連続して記述します。 このコードを見てください:
console.log(/\d-\d-\d-\d/.test('1-2-3-4')); // true console.log(/\d-\d-\d-\d/.test('1-23-4')); // false
ご覧のとおり、ここでは文字列をチェックして、ダッシュで区切られた1桁のシーケンスが含まれているかどうかを確認します。 最初の行はこのパターンに一致し、2行目は一致しません。
ダッシュの数が1以上の場合、ダッシュの前後の桁数が問題にならない場合はどうしますか? この状況では、
+記号を使用して、
/dパターンが1回以上発生する可能性があることを示すことができます。 これは次のようなものです。
console.log(/\d+-\d+/.test('12-34')); // true console.log(/\d+-\d+/.test('1-234')); // true console.log(/\d+-\d+/.test('-34')); // false
私たちの生活を楽にするために、ブラケットとグループ式を使用して、それらの助けを借りることができます。 猫の鳴き声に似た行に何かがあるかどうかを確認したいとしましょう。 これを行うには、次の設計を使用できます。
console.log(/me+(ow)+w/.test('meeeeowowoww'));
わかった。 この式をさらに詳しく見てみましょう。 実際、ここでは多くの興味深いことが起こっています。
これが正規表現です。
/me+(ow)+w/
m単一の文字m対応します。
e+ -1回以上繰り返される文字e対応します。
(ow)+ 、1回以上繰り返されたow一致します。
w単一の文字w対応します。
その結果、この式は文字列を次のように解釈します。
'm' + 'eeee' +'owowow' + 'w'
ご覧のとおり、かっこで囲まれた式の直後に
+などの演算子が使用されている場合、かっこ内のすべてに適用されます。
ここに別の例があります、それは演算子の使用について
? 。 疑問符は、文字列内の先行文字の存在がオプションであることを示します。
これを見てください:
console.log(/cats? says?/i.test('the Cat says meow')); // true console.log(/cats? says?/i.test('the Cats say meow')); // true
ご覧のとおり、各式は
true返し
true 。 これは、
catおよび
sayシーケンスの末尾
s文字をオプションにしたためです。 さらに、
iフラグが正規表現の最後にあることに気付くかもしれません。 彼のおかげで、文字列を分析するとき、大文字と小文字は無視されます。 これが、正規表現が
cat文字列と
Cat文字列の両方に応答する理由です。
サービスキャラクターのエスケープについて
正規表現はスラッシュで囲まれています。 また、
+ ? 、その他には特別な意味があります。 文字列でこれらの特殊文字を検索する必要がある場合は、バックスラッシュでエスケープする必要があります。 これは次のようなものです。
var slash = /\//; var qmark = /\?/;
さらに、異なる文字列表現を使用して同じ文字列構造を検索できることに注意することが重要です。 次に例を示します。
\dは[0-9]と同じです。 これらの表現はそれぞれ、デジタル文字に対応しています。
\wは[A-Za-z0-9_]と同じです。 両方とも、文字列内で単一の英数字またはアンダースコアを検索します。
プロジェクト#1:キャメルスタイルで構築された行にスペースを追加する
ここで、知識を実践に移します。 最初のプロジェクトでは、
CamelCaseような文字列を受け取り、それが構成する個々の単語の間にスペースを追加する関数を作成します。
removeCcと呼ぶ既製の関数を使用すると、次のようになります。
removeCc('camelCase') // => 'camel Case'
まず、文字列を受け取って新しい文字列を返す関数のワイヤフレームを作成する必要があります。
function removeCc(str){
ここで行う必要があるのは、入力データを処理する正規表現を使用するこの関数の
return式に構造を書くことだけです。 これを行うには、まず、文字の範囲を指定し、文字列内でグローバル検索を提供する構造を使用して、文字列内のすべての大文字を見つける必要があります。
/[AZ]/g
この正規表現は、
camelCase行の文字
Cに応答します。 そして、この文字
C前にスペースを追加する方法は?
これを行うには、エキサイティングな括弧が必要です。 正規表現では、キャプチャブラケットを使用して一致を見つけ、それらを記憶します。 これにより、保存された値を必要なときに使用できます。 ブラケットをキャプチャする方法は次のとおりです。
// /([AZ])/ // $1
ここで、キャプチャされた値を参照するために
$1コンストラクトを使用していることがわかります。 式に2組のキャプチャブラケットがある場合、式
$1および
$2を使用して、キャプチャされた値を左から右の順に参照できることに注意してください。 同時に、特定の状況で必要な回数だけエキサイティングなブラケットを使用できます。
括弧で値を取得する必要がないことに注意してください。 使用できないか、ビュー構成体
(?:x)非キャプチャブラケットを使用できます。 この例では、
xと一致しますが、記憶されていません。
プロジェクトに戻りましょう。 ブラケットのキャプチャを操作するために使用できる
Stringオブジェクトメソッドがあります。これは
.replace()です。 これを使用するために、文字列で大文字を検索します。 置換値を表すメソッドの2番目の引数は、保存された値になります。
function removeCc(str){ return str.replace(/([AZ])/g, '$1'); }
まだ目標に到達していませんが、すでに解決策に近づいています。 コードをもう一度見てください。 ここで大文字をキャプチャし、同じ文字に変更します。 そして、それらの前にギャップを作る必要があります。 これは非常に簡単です-
$1変数の前にスペースを追加するだけです。 結果として、関数が返す文字列の各大文字の前にスペースがあります。 その結果、次のことができます。
function removeCc(str){ return str.replace(/([AZ])/g, ' $1'); } removeCc('camelCase') // 'camel Case' removeCc('helloWorldItIsMe') // 'hello World It Is Me'
プロジェクト#2:文字列から大文字を削除する
ラクダスタイルで記録された線を通常の形に戻します。 これまでのところ、この問題は部分的にしか解決されていません。 そして今、私たちは最終行に過剰な量の大文字があるという事実に満足していません。
次に、文字列から余分な大文字を削除し、大文字に置き換えます。 さらに読む前に、この問題を振り返り、解決策を見つけてください。 ただし、成功しなかった場合、落胆しないでください。私たちの問題の解決策は、単純ではありますが、非常に単純とは言えません。
したがって、最初に必要なのは、文字列内のすべての大文字を選択することです。 ここでは、前の例と同じ構成が使用されます。
/[AZ]/g
ここでは、おなじみの
.replace()メソッドを使用しますが、今回は、このメソッドを呼び出すときに新しいものが必要です。 必要なものの概要は次のとおりです。 疑問符は、この新しいまだ未知のコードを示しています。
function lowerCase(str){ return str.replace(/[AZ]/g, ???); }
.replace()メソッドは、関数を2番目のパラメーターとして使用できるという点で注目に値します。 この関数は、一致が見つかった後に呼び出され、この関数が返すものは、正規表現で見つかったものを置き換える文字列として使用されます。
グローバル検索フラグも使用する場合、文字列で見つかったパターンとの一致ごとに関数が呼び出されます。 これを念頭に置いて、
Stringオブジェクトの
.toLowerCase()メソッドを使用して、入力文字列を必要なフォームに変換できます。 上記の観点から、問題の解決方法は次のようになります。
function lowerCase(str){ return str.replace(/[AZ]/g, u => u.toLowerCase()); } lowerCase('camel Case') // 'camel case' lowerCase('hello World It Is Me') // 'hello world it is me'
プロジェクト番号3:行の最初の単語の最初の文字を大文字に変換
これが最後のトレーニングプロジェクトになり、処理された文字列の最初の文字を大文字にします。 新機能に期待することは次のとおりです。
capitalize('camel case') // => 'Camel case'
ここでは、以前と同様に、
.replace()メソッドを使用します。 ただし、今回は文字列の最初の文字のみを見つける必要があります。 これを行うには、
^文字を使用します。 上記の例のいずれかを思い出してください。
console.log(/cat/.test('the cat says meow'));
テンプレートの先頭に
^文字を追加した場合、このコンストラクトは戻りません。 これは、
catという単語が行の先頭にないために発生します。
console.log(/^cat/.test('the cat says meow'));
行の先頭の小文字
^影響
^与えるには、特殊文字
^が必要です。 したがって、
[az]構造の直前に追加します。 その結果、正規表現は小文字の文字列の最初の文字にのみ応答します。
/^[az]/
さらに、ここでは、テンプレートと一致するものを1つだけ見つける必要があるため、グローバル検索フラグを使用しません。 あとは、見つかった文字を大文字に変換するだけです。 これは、文字列メソッド
.toUpperCase()を使用して実行できます。
function capitalize(str){ return str.replace(/^[az]/, u => u.toUpperCase()); } capitalize('camel case') // 'Camel case' capitalize('hello world it is me') // 'Hello world it is me'
以前に作成した機能を共有する
これで、CamelStyleで記述された行を、スペースで区切られ、大文字で始まる個々の単語に変換するために必要なすべてが揃いました。これらの行内の単語は大文字で記述されます。 新しく作成した機能の共有は次のようになります。
function removeCc(str){ return str.replace(/([AZ])/g, ' $1'); } function lowerCase(str){ return str.replace(/[AZ]/g, u => u.toLowerCase()); } function capitalize(str){ return str.replace(/^[az]/, u => u.toUpperCase()); } capitalize(lowerCase(removeCc('camelCaseIsFun')));
まとめ
ご覧のように、正規表現は準備のできていない人には非常に珍しいように見えますが、習得することはできます。 正規表現を学ぶ最良の方法は練習です。 以下を試してみることをお勧めします。作成した3つの関数に基づいて、渡された文字列(キャメルケースなど)を通常の文に変換し、最後の単語の後にピリオドを追加する関数を作成します。
親愛なる読者! 議論したばかりの関数を作成できた場合は、コメントでそのコードを共有することをお勧めします。 また、正規表現に精通している場合は、この知り合いが実際のプロジェクトで役立ったかどうかを教えてください。
さて、正規表現についての
トップHabrapostov 。