Відповіді:
exec
повертає об'єкт із index
властивістю:
var match = /bar/.exec("foobar");
if (match) {
console.log("match found at " + match.index);
}
І для кількох матчів:
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
console.log("match found at " + match.index);
}
re
змінної та додавання g
модифікатора мають важливе значення! Інакше ви отримаєте нескінченну петлю.
undefined
. jsfiddle.net/6uwn1vof/2, який не є подібним до пошуку прикладом.
g
прапор і він запрацює. Оскільки match
це функція рядка, а не регулярний вираз, він не може бути подібним до стану exec
, тому він лише трактує його як exec
(тобто має властивість індексу), якщо ви не шукаєте глобальну відповідність ... тому що тоді стаціонарність не має значення .
Ось що я придумав:
// 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
також працює для кінцевої позиції.
match.index + match[0].length - 1
?
.slice()
і .substring()
. Як ви говорите, інклюзивний кінець був би на 1 менше. (Будьте уважні, що інклюзивне зазвичай означає індекс останнього знаку всередині матчу, якщо тільки це порожній матч, де це 1 перед матчем і може бути -1
поза рядком цілком для порожнього матчу на старті ...)
З Документів developer.mozilla.org про .match()
метод String :
Повернений масив має додаткове властивість введення, яке містить початковий рядок, який був проаналізований. Крім того, він має властивість індексу, яка представляє нульовий індекс відповідності в рядку .
У роботі з неглобальним регулярним виразом (тобто жодним g
прапором у вашому регулярному виразі) значення, яке повертається, .match()
має index
властивість ... все, що вам потрібно зробити, - це отримати доступ до нього.
var index = str.match(/regex/).index;
Ось приклад, який показує, що він також працює:
var str = 'my string here';
var index = str.match(/here/).index;
alert(index); // <- 10
Я успішно протестував це все до IE5.
Можна використовувати search
метод String
об’єкта. Це працюватиме лише для першого матчу, але інакше зробить те, що ви описуєте. Наприклад:
"How are you?".search(/are/);
// 4
Ось класна функція, яку я виявив нещодавно, я спробував це на консолі і, здається, працює:
var text = "border-bottom-left-radius";
var newText = text.replace(/-/g,function(match, index){
return " " + index + " ";
});
Що повернулося: "межа 6 знизу 13 зліва від радіуса 18"
Тож, здається, це те, що ви шукаєте.
arguments
. Не "другий аргумент". Аргументи функції "повний матч, group1, group2, ...., індекс відповідності, повний рядок, протиставлений"
У сучасних браузерах ви можете це зробити за допомогою string.matchAll () .
Користь від цього підходу в RegExp.exec()
тому, що він не покладається на те, що регулярний вираз буде ставитись як у відповіді @ Gumbo .
let regexp = /bar/g;
let str = 'foobarfoobar';
let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
console.log("match found at " + match.index);
});
Цей член fn повертає масив на основі 0 позицій, якщо такі є, вхідного слова всередині об'єкта 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 ;
}
Тепер спробуйте
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 ) );
Ви також можете вводити регулярні вирази:
var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );
Тут отримується індекс позиції лінійного члена.
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
тут якраз знаходить наступне виникнення тексту, захопленого матчем, який не обов'язково відповідає. JS regex підтримує умови для тексту поза захопленням з lookahead. Наприклад, searchIndex("foobarfoobaz", "foo(?=baz)", true)
слід давати [6]
, ні [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
або
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