否定先読み
※String#split
版は必要なら、Array#filter
で「空文字の要素」を除去。
JavaScript
1const string = `12:44 hogehogehogehoge
2fogefogefoge 01:30
3fogefoge 5:30 hogehoge`;
4
5const result1 = string.split(/([0-5]?\d:[0-5]?\d)/),
6 result2 = string.match(/[0-5]?\d:[0-5]?\d|(?:(?![0-5]?\d:[0-5]?\d)[\s\S])+/g);
7
8console.log(JSON.stringify(result1)); // ["","12:44"," hogehogehogehoge\nfogefogefoge ","01:30","\nfogefoge ","5:30"," hogehoge"]
9console.log(JSON.stringify(result2)); // ["12:44"," hogehogehogehoge\nfogefogefoge ","01:30","\nfogefoge ","5:30"," hogehoge"]
文法規則
ざっくり書きましたが、本来は例えば、下記文字列に部分一致しても良いのか、をしっかり考えて正規表現を書くのが正道です。
JavaScript
1console.log('111:222:333:444'.match(/([0-5]?\d:[0-5]?\d)/g)); // ["11:22", "2:33", "3:44"]
2console.log('1:2:3:4'.match(/([0-5]?\d:[0-5]?\d)/g)); // ["1:2", "3:4"]
3console.log('23:35:49'.match(/([0-5]?\d:[0-5]?\d)/g)); // ["23:35"]
この場合、「マッチしない文字列」でこれらを消費してしまえば、「マッチさせない文字列」として扱う事が可能ですが、
- 「マッチする文字列」の文法規則
- 「マッチしない文字列」の文法規則
はそれぞれ独立して定義するので、「マッチする文字列」から「マッチしない文字列」の正規表現が自動的に決定されるものではありません。
「先読み」「後読み」を駆使すれば、自動的に決定する完璧な「マッチする文字列の正規表現」が実現できなくもないですが、「後読み」の実装が不安定です。
JavaScript
1const fix1 = string => string.match(/\D*(?:\d+(?::\d+){2,}|(?![0-5]?\d:[0-5]?\d)[\s\S])+|[0-5]?\d:[0-5]?\d/g);
2
3console.log(fix1('111:222:333:444')); // ["111:222:333:444"]
4console.log(fix1('1:2:3:4')); // ["1:2:3:4"]
5console.log(fix1('23:35:49')); // ["23:35:49"]
Re: Kimsehwa さん