Risposte:
exec
restituisce un oggetto con una index
proprietà:
var match = /bar/.exec("foobar");
if (match) {
console.log("match found at " + match.index);
}
E per più partite:
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
console.log("match found at " + match.index);
}
re
come variabile e l'aggiunta del g
modificatore sono entrambi fondamentali! Altrimenti otterrai un ciclo infinito.
undefined
. jsfiddle.net/6uwn1vof/2 che non è un esempio di ricerca come il tuo.
g
bandiera e funzionerà. Poiché match
è una funzione della stringa, non della regex di cui non può essere stateful exec
, quindi la tratta solo come exec
(cioè ha una proprietà index) se non stai cercando una corrispondenza globale ... perché quindi lo statefulness non ha importanza .
Ecco cosa mi è venuto in mente:
// 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].length
funziona anche per la posizione finale.
match.index + match[0].length - 1
?
.slice()
e .substring()
. La fine inclusiva sarebbe 1 in meno come dici tu. (Fai attenzione che inclusivo di solito significhi un indice dell'ultimo carattere all'interno della partita, a meno che non sia una partita vuota in cui è 1 prima della partita e potrebbe essere -1
al di fuori della stringa per una partita vuota all'inizio ...)
Dai documenti developer.mozilla.org sul .match()
metodo String :
L'array restituito ha una proprietà di input aggiuntiva, che contiene la stringa originale analizzata. Inoltre, ha una proprietà index, che rappresenta l'indice in base zero della corrispondenza nella stringa .
Quando si ha a che fare con una regex non globale (ovvero, nessuna g
bandiera sul proprio regex), il valore restituito da .match()
ha una index
proprietà ... tutto quello che devi fare è accedervi.
var index = str.match(/regex/).index;
Ecco un esempio che mostra che funziona anche:
var str = 'my string here';
var index = str.match(/here/).index;
alert(index); // <- 10
Ho testato con successo tutto questo fino a IE5.
È possibile utilizzare il search
metodo String
dell'oggetto. Funzionerà solo per la prima partita, ma altrimenti farà ciò che descrivi. Per esempio:
"How are you?".search(/are/);
// 4
Ecco una bella funzionalità che ho scoperto di recente, l'ho provato sulla console e sembra funzionare:
var text = "border-bottom-left-radius";
var newText = text.replace(/-/g,function(match, index){
return " " + index + " ";
});
Che ha restituito: "bordo 6 inferiore 13 sinistra 18 raggio"
Quindi questo sembra essere quello che stai cercando.
arguments
essere la posizione. Non "il secondo argomento". Gli argomenti della funzione sono "corrispondenza completa, gruppo1, gruppo2, ...., indice di corrispondenza, stringa completa confrontata con"
Nei browser moderni, puoi farlo con string.matchAll () .
Il vantaggio di questo approccio vs RegExp.exec()
è che non si basa sul fatto che la regex sia stateful, come nella risposta di @ Gumbo .
let regexp = /bar/g;
let str = 'foobarfoobar';
let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
console.log("match found at " + match.index);
});
Questo membro fn restituisce un array di posizioni basate su 0, se presenti, della parola di input all'interno dell'oggetto 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 ;
}
Adesso prova
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 ) );
Puoi anche inserire espressioni regolari:
var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );
Qui si ottiene l'indice di posizione del termine lineare.
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
qui trova solo la prossima occorrenza del testo catturato dalla corrispondenza, che non è necessariamente la corrispondenza. JS regex supporta le condizioni sul testo al di fuori dell'acquisizione con lookahead. Ad esempio searchIndex("foobarfoobaz", "foo(?=baz)", true)
dovrebbe dare [6]
, no [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
o
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