Odpowiedzi:
execzwraca obiekt z indexwłaściwością:
var match = /bar/.exec("foobar");
if (match) {
console.log("match found at " + match.index);
}
Oraz dla wielu dopasowań:
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
console.log("match found at " + match.index);
}
rezmiennej jako zmiennej i dodanie gmodyfikatora są kluczowe! W przeciwnym razie otrzymasz niekończącą się pętlę.
undefined. jsfiddle.net/6uwn1vof/2, który nie jest przykładem podobnym do wyszukiwania, jak twój.
gflagę i zadziała. Ponieważ matchjest funkcją ciągu, a nie wyrażenia regularnego, nie może być stanową exec, więc traktuje ją tylko jako exec(tj. Ma właściwość index), jeśli nie szukasz globalnego dopasowania ... ponieważ wtedy stan nie ma znaczenia .
Oto, co wymyśliłem:
// 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);
}
match.index + match[0].lengthdziała również dla pozycji końcowej.
match.index + match[0].length - 1?
.slice()i .substring(). Koniec obejmujący byłby o 1 mniej, jak mówisz. (Uważaj, że dołączenie zwykle oznacza indeks ostatniego znaku wewnątrz dopasowania, chyba że jest to pusty mecz, w którym jest 1 przed dopasowaniem i może znajdować -1się całkowicie poza ciągiem dla pustego dopasowania na początku ...)
Z dokumentacji developer.mozilla.org na temat .match()metody String :
Zwrócona Array ma dodatkową właściwość wejściową, która zawiera oryginalny ciąg, który został przeanalizowany. Ponadto ma właściwość index, która reprezentuje liczony od zera indeks dopasowania w ciągu .
Kiedy mamy do czynienia z nieglobalnym wyrażeniem regularnym (tj. Brakiem gflagi w Twoim wyrażeniu regularnym), wartość zwracana przez .match()ma indexwłaściwość… wszystko, co musisz zrobić, to uzyskać do niego dostęp.
var index = str.match(/regex/).index;
Oto przykład pokazujący, że również działa:
var str = 'my string here';
var index = str.match(/here/).index;
alert(index); // <- 10
Z powodzeniem przetestowałem to aż do IE5.
Możesz użyć searchmetody Stringobiektu. To zadziała tylko dla pierwszego dopasowania, ale poza tym zrobi to, co opisujesz. Na przykład:
"How are you?".search(/are/);
// 4
Oto fajna funkcja, którą niedawno odkryłem, wypróbowałem to na konsoli i wydaje się, że działa:
var text = "border-bottom-left-radius";
var newText = text.replace(/-/g,function(match, index){
return " " + index + " ";
});
Który zwrócił: „border 6 bottom 13 left 18 radius”
Więc wydaje się, że to jest to, czego szukasz.
arguments. Nie „drugi argument”. Argumentami funkcji są "pełne dopasowanie, grupa1, grupa2, ...., indeks dopasowania, pełny ciąg dopasowany do"
W nowoczesnych przeglądarkach można to osiągnąć za pomocą string.matchAll () .
Zaletą tego podejścia RegExp.exec()jest to, że nie polega ono na tym, że wyrażenie regularne jest stanowe, jak w odpowiedzi @ Gumbo .
let regexp = /bar/g;
let str = 'foobarfoobar';
let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
console.log("match found at " + match.index);
});
Ten element członkowski fn zwraca tablicę pozycji opartych na 0, jeśli takie istnieją, słowa wejściowego wewnątrz obiektu String
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 ;
}
Spróbuj teraz
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 ) );
Możesz także wprowadzić wyrażenia regularne:
var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );
Tutaj otrzymujemy indeks pozycji członu liniowego.
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.indexOftutaj po prostu znajduje następne wystąpienie tekstu przechwyconego przez dopasowanie, które niekoniecznie jest zgodne. JS regex obsługuje warunki w tekście poza przechwytywaniem z wyprzedzeniem. Na przykład searchIndex("foobarfoobaz", "foo(?=baz)", true)powinien dawać [6], a nie [0].
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
lub
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