JavaScriptで正規表現のmatch()の位置を返しますか?


回答:


225

execindexプロパティを持つオブジェクトを返します:

var match = /bar/.exec("foobar");
if (match) {
    console.log("match found at " + match.index);
}

そして、複数のマッチの場合:

var re = /bar/g,
    str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
    console.log("match found at " + match.index);
}


5
ご協力いただきありがとうございます!複数の一致のインデックスを見つける方法も教えてください。
スタガス

9
注:をre変数として使用することとg修飾子を追加することはどちらも重要です!そうしないと、無限ループが発生します。
oriadam

1
@OnurYıldırım-これが動作するjsfiddleです... IE5までさかのぼってテストしました...正常に動作します:jsfiddle.net/6uwn1vof
Jimbo Jonny

1
@JimboJonny、ええと、私は何か新しいことを学びました。テストケースが戻りますundefinedjsfiddle.net/6uwn1vof/2 は、あなたのような検索のような例ではありません。
OnurYıldırım2016年

1
@OnurYıldırım- gフラグを削除すると機能します。以来match、文字列の関数ではなく、正規表現は、それはのようなステートフルすることはできませんexecように、それはそれだけを扱いますので、execあなたがグローバルマッチを探していないならば、ステートフル性は問題ではないので...(つまり、インデックスプロパティを持っています) 。
神保ジョニー

60

これが私が思いついたものです:

// Finds starting and ending positions of quoted text
// in double or single quotes with escape char support like \" \'
var str = "this is a \"quoted\" string as you can 'read'";

var patt = /'((?:\\.|[^'])*)'|"((?:\\.|[^"])*)"/igm;

while (match = patt.exec(str)) {
  console.log(match.index + ' ' + patt.lastIndex);
}


18
match.index + match[0].length終了位置でも機能します。
Beni Cherniavsky-Paskin 2013

本当に素晴らしい- 比較はここにある-Louis
Maddox

1
@ BeniCherniavsky-Paskin、終了位置はmatch.index + match[0].length - 1どうでしょう?
David

1
@David、私は例えば.slice()やによってとられるように、排他的な終了位置を意味しました.substring()。あなたが言うように、包括的終了は1少なくなります。(それが1だ空一致でない限り、包括的には通常、試合の内部で最後の文字のインデックスを意味することに注意してくださいする前にマッチしてあるかもしれない-1開始時に完全に空の一致のための文字列の外に...)
紅Cherniavsky-Paskin

16

String メソッドに関するdeveloper.mozilla.orgのドキュメントから.match()

返された配列には、解析された元の文字列を含む追加の入力プロパティがあります。さらに、文字列内の一致のゼロから始まるインデックスを表すindexプロパティがあります

非グローバル正規表現(つまり、正規表現にgフラグがない)を処理する場合、によって返される値に.match()indexプロパティがあります...アクセスするだけです。

var index = str.match(/regex/).index;

以下は、同様に機能する例です。

var str = 'my string here';

var index = str.match(/here/).index;

alert(index); // <- 10

私はこれをIE5までずっとテストしてきました。


6

オブジェクトのsearchメソッドを使用できStringます。これは最初の一致に対してのみ機能しますが、それ以外の場合はあなたが説明したことを行います。例えば:

"How are you?".search(/are/);
// 4

6

ここに私が最近発見したクールな機能があります、私はこれをコンソールで試しました、そしてそれはうまくいくようです:

var text = "border-bottom-left-radius";

var newText = text.replace(/-/g,function(match, index){
    return " " + index + " ";
});

返されたもの:「ボーダー6ボトム13左18半径」

だから、これはあなたが探しているもののようです。


6
置換関数がキャプチャグループも追加することに注意してください。位置は、常に置換関数の最後から2番目のエントリであることに注意してくださいarguments。「第二引数」ではありません。関数の引数は、「完全一致、グループ1、グループ2、...、一致のインデックス、完全一致の文字列」です
Mike 'Pomax' Kamermans

1

このメンバーfnは、Stringオブジェクト内の入力ワードの0ベースの位置(ある場合)の配列を返します

String.prototype.matching_positions = function( _word, _case_sensitive, _whole_words, _multiline )
{
   /*besides '_word' param, others are flags (0|1)*/
   var _match_pattern = "g"+(_case_sensitive?"i":"")+(_multiline?"m":"") ;
   var _bound = _whole_words ? "\\b" : "" ;
   var _re = new RegExp( _bound+_word+_bound, _match_pattern );
   var _pos = [], _chunk, _index = 0 ;

   while( true )
   {
      _chunk = _re.exec( this ) ;
      if ( _chunk == null ) break ;
      _pos.push( _chunk['index'] ) ;
      _re.lastIndex = _chunk['index']+1 ;
   }

   return _pos ;
}

今してみてください

var _sentence = "What do doers want ? What do doers need ?" ;
var _word = "do" ;
console.log( _sentence.matching_positions( _word, 1, 0, 0 ) );
console.log( _sentence.matching_positions( _word, 1, 1, 0 ) );

正規表現を入力することもできます。

var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );

ここでは、線形項の位置インデックスを取得します。


1
var str = "The rain in SPAIN stays mainly in the plain";

function searchIndex(str, searchValue, isCaseSensitive) {
  var modifiers = isCaseSensitive ? 'gi' : 'g';
  var regExpValue = new RegExp(searchValue, modifiers);
  var matches = [];
  var startIndex = 0;
  var arr = str.match(regExpValue);

  [].forEach.call(arr, function(element) {
    startIndex = str.indexOf(element, startIndex);
    matches.push(startIndex++);
  });

  return matches;
}

console.log(searchIndex(str, 'ain', true));

これは誤りです。str.indexOfここでは、一致によってキャプチャされたテキストの次の出現を検出しますが、これは必ずしも一致ではありません。JS regexは、先読みによるキャプチャの外側のテキストの条件をサポートします。たとえば、searchIndex("foobarfoobaz", "foo(?=baz)", true)与えるべきでは[6]ありません[0]
rakslice

なぜ `[] .forEach.call(arr、function(element)`なぜarr.forEachまたはarr.mapではない
Ankit Kumar

1

最近のブラウザーでは、string.matchAll()使用してこれを実現できます。

このアプローチと比較した利点RegExp.exec()は、@ Gumboの回答のように、正規表現がステートフルであることに依存しないことです。

let regexp = /bar/g;
let str = 'foobarfoobar';

let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
    console.log("match found at " + match.index);
});


-1
function trimRegex(str, regex){
    return str.substr(str.match(regex).index).split('').reverse().join('').substr(str.match(regex).index).split('').reverse().join('');
}

let test = '||ab||cd||';
trimRegex(test, /[^|]/);
console.log(test); //output: ab||cd

または

function trimChar(str, trim, req){
    let regex = new RegExp('[^'+trim+']');
    return str.substr(str.match(regex).index).split('').reverse().join('').substr(str.match(regex).index).split('').reverse().join('');
}

let test = '||ab||cd||';
trimChar(test, '|');
console.log(test); //output: ab||cd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.