Réponses:
exec
renvoie un objet avec une index
propriété:
var match = /bar/.exec("foobar");
if (match) {
console.log("match found at " + match.index);
}
Et pour plusieurs matchs:
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
console.log("match found at " + match.index);
}
re
comme variable et ajouter le g
modificateur sont tous deux cruciaux! Sinon, vous obtiendrez une boucle sans fin.
undefined
. jsfiddle.net/6uwn1vof/2 qui n'est pas un exemple de recherche comme le vôtre.
g
drapeau et cela fonctionnera. Étant donné que match
c'est une fonction de la chaîne, pas de l'expression régulière, elle ne peut pas être avec état exec
, donc elle ne la traite que comme exec
(c'est-à-dire qu'elle a une propriété d'index) si vous ne recherchez pas une correspondance globale ... parce que l'état n'a pas d'importance .
Voici ce que j'ai trouvé:
// 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
fonctionne également pour la position finale.
match.index + match[0].length - 1
?
.slice()
et .substring()
. La fin inclusive serait de 1 de moins comme vous le dites. (Attention, inclusif signifie généralement l'index du dernier caractère à l'intérieur de la correspondance, à moins qu'il ne s'agisse d'une correspondance vide où il est 1 avant la correspondance et pourrait être -1
entièrement en dehors de la chaîne pour une correspondance vide au début ...)
À partir de la documentation de developer.mozilla.org sur la .match()
méthode String :
Le tableau retourné a une propriété d'entrée supplémentaire, qui contient la chaîne d'origine qui a été analysée. De plus, il possède une propriété index, qui représente l'index de base zéro de la correspondance dans la chaîne .
Lorsque vous traitez avec une regex non globale (c'est-à-dire pas de g
drapeau sur votre regex), la valeur renvoyée par .match()
a une index
propriété ... tout ce que vous avez à faire est d'y accéder.
var index = str.match(/regex/).index;
Voici un exemple montrant que cela fonctionne également:
var str = 'my string here';
var index = str.match(/here/).index;
alert(index); // <- 10
J'ai testé cela avec succès depuis IE5.
Vous pouvez utiliser la search
méthode de l' String
objet. Cela ne fonctionnera que pour le premier match, mais fera autrement ce que vous décrivez. Par exemple:
"How are you?".search(/are/);
// 4
Voici une fonctionnalité intéressante que j'ai découverte récemment, j'ai essayé ceci sur la console et cela semble fonctionner:
var text = "border-bottom-left-radius";
var newText = text.replace(/-/g,function(match, index){
return " " + index + " ";
});
Qui a renvoyé: "border 6 bottom 13 left 18 radius"
Donc, cela semble être ce que vous recherchez.
arguments
qui est la position. Pas "le deuxième argument". Les arguments de la fonction sont "correspondance complète, groupe1, groupe2, ...., index de correspondance, chaîne complète mise en correspondance"
Dans les navigateurs modernes, vous pouvez accomplir cela avec string.matchAll () .
L'avantage de cette approche RegExp.exec()
est qu'elle ne repose pas sur le fait que l'expression régulière soit avec état, comme dans la réponse de @ Gumbo .
let regexp = /bar/g;
let str = 'foobarfoobar';
let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
console.log("match found at " + match.index);
});
Ce membre fn renvoie un tableau de positions basées sur 0, le cas échéant, du mot d'entrée à l'intérieur de l'objet 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 ;
}
Maintenant essaye
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 ) );
Vous pouvez également saisir des expressions régulières:
var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );
Ici, on obtient l'indice de position du terme linéaire.
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
ici trouve juste l'occurrence suivante du texte capturé par la correspondance, qui n'est pas nécessairement la correspondance. JS regex prend en charge les conditions sur le texte en dehors de la capture avec anticipation. Par exemple searchIndex("foobarfoobaz", "foo(?=baz)", true)
devrait donner [6]
, non [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
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