正規表現のスキルアップ攻略


数年前にVIMエディタに触れたばかりの頃、敬遠していたのを覚えています.これは複雑だと思います.エディタを作るのにこんなに時間がかかります.疲れています. 型のプログラマーには向いていません.何度も振り回した後、ネズミのおじさんのこのvim練習攻略を見た.数週間練習した上に、実戦を繰り返した.今ではVIMが私の唯一のエディタになりました.この文章の啓発を受けて の練習攻略を決定した.同じように、ここでもっと注目しているのは正則的な実戦部分です.つまり、それを利用してあなたの手元の問題を解決し、見ただけで得られます.あなたが一つのことをよく知っているだけで、その背後にある思想原理を理解することに興味があると思います.
全体の攻略は4つの部分に分かれており、基礎部分には一般プログラマーが使う80パーセントの機能が含まれており、次に少数のプログラマーだけが日常的な工程で高級部分に応用できるテクニックを紹介し、次にごく少数の人だけが本当に正則を身につけることができる超能力を紹介した(どうせ私はまだ持っていない).最後にjsの中で正則を運用するいくつかの実践について話します.操作例を容易にするために、主にjavascriptによって提供されるいくつかの方法を使用して試験を完了する.

生き延びる


その名の通り、これらのテクニックを知ってから、正則を利用して日常的な問題を解決することができます.
テキストの一致
探し出すLeBron文字列
var str = 'Hello my name is LeBron leBron james';
str.match(/LeBron/);
//          g   ,    RegExp.exec(str)      
[ 'LeBron',
index: 17,
input: 'Hello my name is LeBron leBron james' ]

複数の結果を一致させ、大文字と小文字を無視
var str = 'Hello my name is LeBron leBron james';
str.match(/LeBron/ig);
[ 'LeBron', 'leBron' ]

任意の文字に一致.は改行以外の任意の文字を表すことができる
var str = 'Hello my name is LeBron leBron james';
str.match(/.eBron/g);
[ 'LeBron', 'leBron' ]

特殊文字の一致
正則の中のメタ文字には特殊な意味があり、それ自体にマッチするにはエスケープが必要です.
var str = 'Hello my name is LeBron.james KingJames';
str.match(/\.james/g);
[ '.james' ]

一致するメタ文字自体を覚えるにはエスケープが必要です
文字セットの一致
複数の文字のいずれかに一致
var str = 'Hello my name is LeBron leBron james';
str.match(/[lL]eBron/g);
[ 'LeBron', 'leBron' ]

メタ文字[]は、1つの文字セットと、そのセット内の任意のメンバーと一致する文字セットとを定義するために使用される.
文字集合区間の利用
よくあるのは数字と文字の区間です
var str = 'a1 a2 b1 b2 abc a9 b7 a5';
str.match(/a[1-5]/g);
[ 'a1', 'a2', 'a5' ]

一致しない
var str = 'a1 a2 b1 b2 abc a9 b7 a5';
str.match(/a[^1-5]/g);
[ 'ab', 'a9' ]

ハイフネーション-は特殊な文字です[]の中ではメタ文字で、文字セットの外では普通の文字です.一致しない^もメタ文字です.
よく使われるメタ文字
メタキャラクタエスケープマッチング
var str = 'test arr[10]';
str.match(/arr\[10\]/);
[ 'arr[10]', index: 5, input: 'test arr[10]' ]

空白文字の一致
一般的な空白文字には、改ページ改行、タブなどが含まれます.
一致する数値
var str = 'test arr[10]';
str.match(/arr\[\d\d\]/);
[ 'arr[10]', index: 5, input: 'test arr[10]' ]
\dは数字を表し、\Dは非数字を表す.
一致文字(英数字の下線)
var str = 'test arr[10]';
str.match(/\w\w\w\[\w\w\]/);
[ 'arr[10]', index: 5, input: 'test arr[10]' ]
\wは文字を表し、\Wは非文字を表します.
空白文字の一致
var str = 'test arr[10]';
str.match(/t\sa/);
[ 't a', index: 3, input: 'test arr[10]' ]
\sは文字を表し、\Sは非文字を表す.
特殊進数
16進数はxを接頭辞とし、8進数は0を接頭辞とする.
重複照合
1回または複数回マッチ
var str = 'dasdhld [email protected] [email protected] [email protected] [email protected]';
str.match(/\w+@\w+\.\w+/g);
[ '[email protected]',
'[email protected]',
'[email protected]',
'[email protected]' ]

3番目のメールアドレスの一致が不十分です
str.match(/[\w.]+@[\w.]+\.\w+/g);
[ '[email protected]',
'[email protected]',
'[email protected]',
'[email protected]' ]

任意の回数(*)、0回または1回(?)用法が同じである.+ .
一致指定回数
var str = '4/8/03 10-6-2004 2/2/2 01-01-01';
str.match(/\d{1,2}[-\/]\d{1,2}[-\/]\d{2,4}/g);
[ '4/8/03', '10-6-2004', '01-01-01' ]

マッチングは少なくとも何回繰り返しますか:{n, }トランジションマッチングの防止
var str = '<H1>nihaoH1</H1> <H1>nihao dupH1</H1>';
str.match(/<[hH]1>.*<\/[hH]1>/g);
[ '<H1>nihaoH1</H1> <H1>nihao dupH1</H1>' ]

指定した回数の後に疑問符を付けて、遷移一致の問題を解決します.
str.match(/<[hH]1>.*?<\/[hH]1>/g);
[ '<H1>nihaoH1</H1>', '<H1>nihao dupH1</H1>' ]

より速く、より良く、より強く


位置照合
単語の境界
var str = 'hello he hell';
str.match(/\bhe\b/);
[ 'he', index: 6, input: 'hello he hell' ]

文字列の境界
var str = 'hello he hell';
str.match(/^he/);
[ 'he', index: 0, input: 'hello he hell' ]
^文字列の開始位置を定義し、$文字列の終了位置を定義します.
サブエクスプレッションの使用
IPアドレスを一致させる
var str = 'ip = [120.24.163.198]';
str.match(/(\d{1,3}\.){3}\d{1,3}/g);
[ '120.24.163.198' ]

サブエクスプレッションは独立した全体であり、サブエクスプレッションはカッコ()で囲まなければなりません.
遡及参照
遡及参照によって解決された問題:
var str = '<h1>hi label</h1> <h2>h2 label</h2> <h2>h2 error label</h3>';
str.match(/<[hH][1-9]>.*?<\/[hH][1-9]>/g)
[ '<h1>hi label</h1>',
  '<h2>h2 label</h2>',
  '<h2>h2 error label</h3>' ] 

明らかに3番目の結果は誤ったラベルであり、遡及参照はこの問題を解決するためである.
var str = '<h1>hi label</h1> <h2>h2 label</h2> <h2>h2 error label</h3>';
str.match(/<[hH]([1-9])>.*?<\/[hH]\1>/g)
[ '<h1>hi label</h1>', '<h2>h2 label</h2>' ]

JAvascriptでは\+の数字でサブエクスプレッションを参照します.数値は、サブエクスプレッションが表示される順序によって決まります.
遡及置換
var str = 'Hello , [email protected] is my email address';
str.replace(/\w+[\w.]*@[\w.]+\.\w+/g, "[email protected]");
'Hello , [email protected] is my email address'

JAvascript実装正則置換はStringオブジェクトのreplace関数で行う

せいそくちょうりょく


前後検索
マッチング自体が返されず、マッチング結果の一部ではない正しいマッチング位置を決定するためのモードが必要です.
前方検索(?=)
  //  
  Hello my name is LeBron!
  http://www.baidu.com
  https://www.sina.com.cn
  ftp://192.168.0.1

  //reg
  grep -P '.+(?=:)' ./x.js 

  //output
`http`://www.baidu.com
`https`://www.sina.com.cn
`ftp`://192.168.0.1

一致した:は最終的な結果には現れなかった.javascriptは前方検索のみをサポートする.
埋め込み条件
なぜ条件を埋め込むのですか?いくつかの正規表現の後の判断は、前の判断結果に基づいて行わなければならない.
遡及参照条件
 var str = '<a href="/home"><img src="/images/home.gif"></a> <img src="/images/aboutme.gif">';

str.match(/(<[aA]%s+[^>]+)?<[iI][mM][gG]\s+[^>]+>(?(1)\s*</[Aa]>)/);

Javascriptと正則の結合

javascript言語では、正規表現の処理を実現するためのいくつかの方法が提供されています.

1.exec(RegEx)


一致するRegExメソッドを検索します.
Demo:
var reg = /ab[cx]/g;
var str = 'abcdefabx';
var myArr;
while((myArr = reg.exec(str)) !== null) {
    var msg = 'Found ' + myArr[0] + '.';
    msg += 'Next match starts at ' + reg.lastIndex;
    console.log(msg);
    console.log('myArr:', myArr);
    console.log('reg:', reg);
    console.log('----------------------');
}

output:
[luncher@localhost regex]$ node x.js 
Found abc.Next match starts at 3
myArr: [ 'abc', index: 0, input: 'abcdefabx' ]
reg: /ab[cx]/g
---------------------- Found abx.Next match starts at 9 myArr: [ 'abx', index: 6, input: 'abcdefabx' ] reg: /ab[cx]/g ----------------------

グループキャプチャの有効化
var reg = /(ab)[cx]/g;
var str = 'abcdefabx';
var myArr;
while((myArr = reg.exec(str)) !== null) {
    var msg = 'Found ' + myArr[0] + '.';
    msg += 'Next match starts at ' + reg.lastIndex;
    console.log(msg);
    console.log('myArr:', myArr);
    console.log('reg:', reg);
    console.log('----------------------');
}

output
[luncher@localhost regex]$ node x.js 
Found abc.Next match starts at 3
myArr: [ 'abc', 'ab', index: 0, input: 'abcdefabx' ]
reg: /(ab)[cx]/g
----------------------
Found abx.Next match starts at 9
myArr: [ 'abx', 'ab', index: 6, input: 'abcdefabx' ]
reg: /(ab)[cx]/g
----------------------

正規表現が「g」フラグを使用する場合、execメソッドを複数回実行して、同じ文字列の正常な一致を検索できます.これを行うと、正規表現のlastIndexプロパティで指定された場所から検索が開始されます.regフォント量オブジェクトには、複数行マッチングが有効になっているかどうか、大文字と小文字が無視されているかどうか、グローバルマッチングが行われているかどうかを確認するなど、他のプロパティがあります.

2.test(RegEx)


test()メソッドは、正規表現が指定した文字列と一致するかどうかを確認するための取得を実行します.trueまたはfalseを返します.
Demo
> /https?/.test('https');
true

> /https?/.test('http');
true

> /https?/.test('ftp');
false

RegExオブジェクトのtestメソッドはStringオブジェクトのsearchメソッドと似ています.

3.match(String)


正規表現にgフラグがない場合はRegExpを返す.exec(str)と同じ結果.正規表現にgフラグが含まれている場合、この方法はすべての一致結果を含む配列を返します.一致しない場合はnullを返します.
Demo
> var str = 'hi my name is leBron James or KingLeBron';
> str.match(/[lL]eBron\s?/);
[ 'leBron ',
  index: 14,
  input: 'hi my name is leBron James or KingLeBron' ]
> str.match(/[lL]eBron\s?/g);
[ 'leBron ', 'LeBron' ]

4.search(String)


マッチングに成功すると、search()は、文字列内で最初に一致する正規表現のインデックスを返します.そうでなければ、-1を返します.
Demo
[luncher@localhost regex]$ node
> var str = 'ni hao';
> str.search(/[ii]/);
1
> str.search(/[xX]/);
-1

5.split(String)


split()メソッドは,文字列をサブ文字列に分割することによって,1つのStringオブジェクトを1つの文字列配列に分割する.
Demo
> var str = '{k1: 1, k2: 2, k3: 3}';
> str.split(/[{}]/);
[ '', 'k1: 1, k2: 2, k3: 3', '' ]
> str.split(/[{}]/)[1].split(/,/);
[ 'k1: 1', ' k2: 2', ' k3: 3' ]
> 

6.replace(String)


replace()メソッドは、元の文字列の一部またはすべての一致項目を置換値(replacement)で置換し、置換後の文字列を返します.この置換モードは、文字列またはRegExp(正規表現)であってもよく、置換値は文字列または関数であってもよい.
Demo1
> var str ='leBron James';
> str.replace(/(\w+)\s(\w+)/, "$2, $1");
'James, leBron'
> 
$2は一致する文字列jamesを表し、$1は一致する文字列leBronを表す.
Demo2
> var str ='leBron James';
> str.replace(/(\w+)\s(\w+)/, function(match, p1, p2, offset, string) {
... return p1.toUpperCase()+p2.toUpperCase();});
'LEBRONJAMES'

参考文献:1.Javascript標準ライブラリ2.正規表現は必ず知っている