Bir regex match () pozisyonlarını Javascript?


Yanıtlar:


225

execindexözelliği olan bir nesne döndürür :

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

Birden fazla eşleşme için:

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


5
Yardımınız için teşekkürler! Ayrıca bana birden fazla eşleşmenin dizinini nasıl bulabilirim?
Şubat'ta stagas

9
Not: redeğişken olarak kullanmak ve gdeğiştiriciyi eklemek çok önemlidir! Aksi takdirde sonsuz bir döngü elde edersiniz.
oriadam

1
@ OnurYıldırım - İşte bir jsfiddle çalışıyor ... IE5'e kadar test ettim ... harika çalışıyor: jsfiddle.net/6uwn1vof
Jimbo Jonny

1
@JimboJonny, hm iyi yeni bir şey öğrendim. Test durumum geri dönüyor undefined. Sizinki gibi arama benzeri bir örnek olmayan jsfiddle.net/6uwn1vof/2 .
Onur Yıldırım

1
@ OnurYıldırım - gBayrağı kaldırdığınızda işe yarayacaktır. Yana matchdize bir fonksiyonu değil, regex neye durum bilgisi olamaz execgibi o yüzden sadece davranır onu, execsonra da statefulness önemli değil çünkü ... global maç için arıyoruz değil (yani bir indeks özelliğine sahiptir) .
Jimbo Jonny

60

İşte ben geldim:

// 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].lengthson konum için de çalışır.
Beni Cherniavsky-Paskin


1
@ BeniCherniavsky-Paskin, son pozisyon olmaz mıydı match.index + match[0].length - 1?
David

1
@David, mesela .slice()ve tarafından alındığı gibi münhasır son konum demek istedim .substring(). Kapsayıcı son dediğin gibi 1 daha az olurdu. (Kapsayıcı, maçtan önce 1 olduğu -1ve başlangıçta boş maç için tamamen ipin dışında olabileceği boş bir maç olmadığı sürece, genellikle maç içindeki son karakter dizini anlamına geldiğine dikkat edin .)
Beni Cherniavsky-Paskin

16

Gönderen developer.mozilla.org dize üzerinde dokümanlar .match()yöntemle:

Döndürülen Dizi, ayrıştırılan orijinal dizeyi içeren ekstra bir girdi özelliğine sahiptir. Ayrıca , dizedeki eşleşmenin sıfır temelli dizinini temsil eden bir dizin özelliğine sahiptir .

Küresel olmayan bir regex ile uğraşırken (yani, regex'inizde hiçbir gbayrak yoksa), döndürülen değerin .match()bir indexözelliği vardır ... tek yapmanız gereken ona erişmek.

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

Burada da çalıştığını gösteren bir örnek:

var str = 'my string here';

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

alert(index); // <- 10

Başarıyla geri IE5 için bu test ettim.


6

Nesnenin searchyöntemini kullanabilirsiniz String. Bu sadece ilk maçta işe yarayacaktır, aksi takdirde tarif ettiğiniz şeyi yapacaktır. Örneğin:

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

6

İşte son zamanlarda keşfettiğim harika bir özellik, bunu konsolda denedim ve işe yarıyor gibi görünüyor:

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

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

Hangi döndü: "sınır 6 alt 13 sol 18 yarıçapı"

Bu aradığınız şey gibi görünüyor.


6
değiştirme işlevlerinin de yakalama grupları eklediğine dikkat edin, bu nedenle her zaman konum değiştirme işlevinde ikinci-son giriş argumentsolduğunu unutmayın. "İkinci argüman" değil. İşlev argümanları "tam eşleme, grup1, grup2, ...., eşleşme endeksi, tam dize karşı"
Mike 'Pomax' Kamermans

2

Modern tarayıcılarda bunu string.matchAll () ile yapabilirsiniz .

Bu yaklaşımın yararı RegExp.exec(), @ Gumbo'nun cevabında olduğu gibi, normal ifadenin durumsal olmasına dayanmamasıdır .

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

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


1

Bu üye fn, String nesnesinin içindeki giriş sözcüğünün 0 tabanlı konumlarından oluşan bir dizi döndürür

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 ;
}

Şimdi dene

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 ) );

Ayrıca düzenli ifadeler de girebilirsiniz:

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

Burada lineer terimin pozisyon indeksi elde edilir.


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));

Bu yanlış. str.indexOfburada sadece maç tarafından yakalanan metnin bir sonraki tekrarını bulur; JS regex, önden okuma ile yakalama dışındaki metindeki koşulları destekler. Örneğin searchIndex("foobarfoobaz", "foo(?=baz)", true)vermemeli [6], vermemeli [0].
rakslice

neden `[] .forEach.call (arr, function (element)` `neden arr forEach veya arr.map değil
Ankit Kumar

-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

veya

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.