是否有一种方法来检索(开始)字符的位置在一个正则匹配()在Javascript的结果字符串?
当前回答
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
or
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
其他回答
这是我最近发现的一个很酷的功能,我在主机上尝试了一下,似乎很管用:
var text = "border-bottom-left-radius";
var newText = text.replace(/-/g,function(match, index){
return " " + index + " ";
});
返回:"border 6 bottom 13 left 18 radius"
看来这就是你要找的东西。
我恐怕之前的答案(基于exec)似乎不工作的情况下,你的正则表达式匹配宽度0。例如(注意:/\b/g是应该找到所有单词边界的正则表达式):
Var re = /\b/g, STR = "hello world"; Var guard = 10; While ((match = re.exec(str)) != null) { Console.log ("match found at " + match.index); If (guard—< 0){ 控制台。错误(“检测到无限循环”) 打破; } }
可以尝试通过让正则表达式匹配至少1个字符来修复这个问题,但这远远不够理想(并且意味着您必须手动在字符串末尾添加索引)。
Var re = /\b /g, STR = "hello world"; Var guard = 10; While ((match = re.exec(str)) != null) { Console.log ("match found at " + match.index); If (guard—< 0){ 控制台。错误(“检测到无限循环”) 打破; } }
一个更好的解决方案(它只适用于较新的浏览器/需要在较旧的/IE版本上进行填充)是使用String.prototype.matchAll()
Var re = /\b/g, STR = "hello world"; console.log(Array.from(str.matchAll(re)).map(match => match.index))
解释:
String.prototype.matchAll()需要一个全局正则表达式(带有全局标志设置g的正则表达式)。然后返回一个迭代器。为了遍历和映射()迭代器,它必须转换为一个数组(这正是array .from()所做的)。与RegExp.prototype.exec()的结果类似,生成的元素根据规范有一个.index字段。
请参阅String.prototype.matchAll()和Array.from() MDN页面了解浏览器支持和填充选项。
编辑:深入挖掘一个所有浏览器都支持的解决方案
RegExp.prototype.exec()的问题是它更新了regex上的lastIndex指针,并且下次开始从以前找到的lastIndex开始搜索。
Var re = /l/g, STR = "hello world"; console.log (re.lastIndex) re.exec (str) console.log (re.lastIndex) re.exec (str) console.log (re.lastIndex) re.exec (str) console.log (re.lastIndex)
只要正则表达式匹配实际上有宽度,这就很有效。如果使用0 width正则表达式,这个指针不会增加,所以你得到了无限循环(注意:/(?=l)/g是l的前向——它在l之前匹配0-width字符串。所以它在第一次调用exec()时正确地去到索引2,然后保持在那里:
Var re = /(?=l)/g, STR = "hello world"; console.log (re.lastIndex) re.exec (str) console.log (re.lastIndex) re.exec (str) console.log (re.lastIndex) re.exec (str) console.log (re.lastIndex)
The solution (that is less nice than matchAll(), but should work on all browsers) therefore is to manually increase the lastIndex if the match width is 0 (which may be checked in different ways) var re = /\b/g, str = "hello world"; while ((match = re.exec(str)) != null) { console.log("match found at " + match.index); // alternative: if (match.index == re.lastIndex) { if (match[0].length == 0) { // we need to increase lastIndex -- this location was already matched, // we don't want to match it again (and get into an infinite loop) re.lastIndex++ } }
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));
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); }
您可以使用String对象的搜索方法。这将只适用于第一个匹配,但在其他情况下将完成您所描述的工作。例如:
"How are you?".search(/are/);
// 4