Ответы:
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
(т.е. имеет свойство index), если вы не ищете глобального соответствия ... потому что тогда состояние не имеет значения ,
Вот что я придумал:
// 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 :
Возвращаемый массив имеет дополнительное входное свойство, которое содержит исходную строку, которая была проанализирована. Кроме того, у него есть свойство index, которое представляет нулевой индекс совпадения в строке .
При работе с неглобальным регулярным выражением (т. Е. Без 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 регулярное выражение поддерживает условия для текста за пределами захвата с предвидением. Например 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