Respostas:
exec
retorna um objeto com uma index
propriedade:
var match = /bar/.exec("foobar");
if (match) {
console.log("match found at " + match.index);
}
E para várias correspondências:
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
console.log("match found at " + match.index);
}
re
como variável e a adição do g
modificador são cruciais! Caso contrário, você obterá um loop infinito.
undefined
. jsfiddle.net/6uwn1vof/2, que não é um exemplo de pesquisa como o seu.
g
bandeira e ela funcionará. Como match
é uma função da string, não da regex, ela não pode ser com estado exec
, portanto, ela só a trata como exec
(por exemplo, tem uma propriedade de índice) se você não está procurando uma correspondência global ... porque a condição de estado não importa .
Aqui está o que eu vim com:
// 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
também funciona para a posição final.
match.index + match[0].length - 1
?
.slice()
e .substring()
. O fim inclusivo seria 1 a menos, como você diz. (Tenha cuidado para que inclusivo geralmente signifique o índice do último caractere dentro da correspondência, a menos que seja uma correspondência vazia onde é 1 antes da correspondência e pode estar -1
fora da cadeia inteiramente para correspondência vazia no início ...)
Nos documentos developer.mozilla.org sobre o .match()
método String :
A matriz retornada possui uma propriedade de entrada extra, que contém a string original que foi analisada. Além disso, possui uma propriedade index, que representa o índice baseado em zero da correspondência na string .
Ao lidar com uma regex não global (ou seja, sem g
sinalização em sua regex), o valor retornado por .match()
possui uma index
propriedade ... tudo o que você precisa fazer é acessá-la.
var index = str.match(/regex/).index;
Aqui está um exemplo mostrando que também funciona:
var str = 'my string here';
var index = str.match(/here/).index;
alert(index); // <- 10
Testei com sucesso isso desde o IE5.
Você pode usar o search
método do String
objeto. Isso funcionará apenas para a primeira partida, mas fará o que você descreve. Por exemplo:
"How are you?".search(/are/);
// 4
Aqui está um recurso interessante que descobri recentemente, tentei isso no console e parece funcionar:
var text = "border-bottom-left-radius";
var newText = text.replace(/-/g,function(match, index){
return " " + index + " ";
});
Que retornou: "borda 6 inferior 13 esquerda 18 raio"
Então, isso parece ser o que você está procurando.
arguments
que é a posição. Não é "o segundo argumento". Os argumentos da função são "correspondência completa, grupo1, grupo2, ...., índice de correspondência, sequência completa correspondida"
Esse membro fn retorna uma matriz de posições baseadas em 0, se houver, da palavra de entrada dentro do objeto 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 ;
}
Agora tente
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 ) );
Você também pode inserir expressões regulares:
var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );
Aqui se obtém o índice de posição do termo linear.
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
aqui apenas encontra a próxima ocorrência do texto capturado pela correspondência, que não é necessariamente a correspondência. O JS regex suporta condições no texto fora da captura com lookahead. Por exemplo, searchIndex("foobarfoobaz", "foo(?=baz)", true)
deve dar [6]
, não [0]
.
Nos navegadores modernos, você pode fazer isso com string.matchAll () .
O benefício dessa abordagem vs RegExp.exec()
é que ela não depende do estado regular, como na resposta da @ Gumbo .
let regexp = /bar/g;
let str = 'foobarfoobar';
let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
console.log("match found at " + match.index);
});
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
ou
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