我想在某个正则表达式上拆分文本,还希望在原始字符串中有一个拆分位置的索引。 在一个简单的例子中:
"bla blabla haha".splitOnRegexWithIndex(whitespaceRegex)
所需的输出是
[["bla", 0], ["blabla", 4], ["haha", 11]]
这里的正则表达式可以是任何东西,而不仅仅是空格,因此分隔符不是固定大小。
在正则表达式上进行分割。我不想使用indexOf
在起始字符串中找到"blabla"
,因为那样的复杂度为O(n 2 ),在我的方案中是不可接受的。>
答案 0 :(得分:4)
您可以使用exec
来检索具有索引的插入器:
const s = "bla blabla haha";
for (let m, reg = /\S+/g; m = reg.exec(s);) {
console.log(m[0], m.index);
}
答案 1 :(得分:3)
您可以使用replace
及其回叫
let str = `bla blabla haha`
let data = []
str.replace(/\S+/g,(m,offset)=>{
data.push([m,offset])
})
console.log(data)
答案 2 :(得分:3)
这是基于.exec
的可能实现:
function split_with_offset(str, re) {
if (!re.global) {
throw "no no no no :(";
}
let results = [];
let m, p;
while (p = re.lastIndex, m = re.exec(str)) {
results.push([str.substring(p, m.index), p]);
}
results.push([str.substring(p), p]);
return results;
}
console.log(split_with_offset("bla blabla haha", /\s+/g));
console.log(split_with_offset(" ", /\s+/g));
console.log(split_with_offset("", /\s+/g));
注意:正则表达式必须设置g
标志。
答案 3 :(得分:3)
好吧,您可以先在正则表达式中使用String.split()
,然后在结果数组上使用Array.map()。像这样:
function splitOnRegexWithIndex(str, regexp)
{
let offset = 0, tmp;
return str
.split(regexp)
.map(s => (tmp = offset, offset += s.length + 1, [s, tmp]));
}
console.log(
JSON.stringify(splitOnRegexWithIndex("bla blabla haha", /\s/))
);
console.log(
JSON.stringify(splitOnRegexWithIndex("bla blabla haha", /b/))
);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
但是,与警告一样,您应该注意,只有在拆分令牌的字符长度为1
时,前一种方法才能很好地工作。但是,如果我们在拆分正则表达式上使用capturing groups,然后在结果数组上使用Array.reduce(),如下所示,就可以推广这种想法。
function splitOnRegexWithIndex(str, regexp)
{
let offset = 0;
// Add capturing group to the regular expression.
regexp = new RegExp("(" + regexp.source + ")");
// Split the string using capturing group and reduce
// the resulting array.
return str.split(regexp).reduce((acc, s, idx) =>
{
if (idx % 2 === 0)
acc.push([s, offset]);
offset += s.length;
return acc;
}, []);
}
console.log(
JSON.stringify(splitOnRegexWithIndex("bla blabla haha", /\s+/))
);
console.log(
JSON.stringify(splitOnRegexWithIndex("abaaagbacccbaaddytbax", /ba+/))
);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
答案 4 :(得分:1)
如果您的正则表达式不是全局的,则会得到两个部分,第一个匹配之前的一个,第二个匹配之后的一个。
gsub(pattern = "PCP", replacement = "", x = x)
答案 5 :(得分:-1)
您可以使用map
和indexOf
来了解原始字符串中的位置:
String.prototype.splitOnRegexWithIndex = function(regex){
var splitted = this.split(regex);
var original = this;
return splitted.map(function(){
return [this, original.indexOf(this)];
});
}