我一直在努力使用javascript字符串方法和正则表达式,我可能会忽略一些显而易见的事情。我希望通过更详细地重述tofutim的question来违反任何协议。对他的问题的回答集中在s.replace()上,但为了使其起作用,你必须知道要替换的子串的出现,替换所有子串,或者能够以某种方式识别要替换的字符串。正则表达式。和他一样,我只有一系列文本偏移,如下所示:
[[5,9], [23,27]]
和这样的字符串:
"eggs eggs spam and ham spam"
考虑到这些限制,是否有一种简单的方法(javaScript或jQuery的快捷方式)来获得这样的字符串?
"eggs <span>eggs</span> spam and ham <span>spam</span>"
我事先并不知道替换字符串是什么,或者基本文本中可能出现的字符串数量。我只知道它们的偏移量,并且仅由我们想要用标签包装的偏移所识别的事件。
有什么想法吗?
答案 0 :(得分:3)
我找到了一种用regexp做的方法。不确定性能,但它简短而且甜美:
/**
* replaceOffset
* @param str A string
* @param offs Array of offsets in ascending order [[2,4],[6,8]]
* @param tag HTML tag
*/
function replaceOffset(str, offs, tag) {
tag = tag || 'span';
offs.reverse().forEach(function(v) {
str = str.replace(
new RegExp('(.{'+v[0]+'})(.{'+(v[1]-v[0])+'})'),
'$1<'+tag+'>$2</'+tag+'>'
);
});
return str;
}
答案 1 :(得分:1)
您可以尝试slice
方法。
var arr = [[5,9], [23,27]];
arr = arr.reverse()
$.each(arr, function(i, v){
var f = v[0], last = v[1];
$('p').html(function(i, v){
var o = v.slice(0, f);
var a = '<span>' + v.slice(f, last) + '</span>';
var c = v.slice(last, -1);
return o+a+c
})
})
答案 2 :(得分:1)
iquick解决方案(未经测试)
function indexWrap(indexArr,str){
// explode into array of each character
var chars = str.split('');
// loop through the MD array of indexes
for(var i=0; i<indexArr.length;i++){
var indexes = indexArr[i];
// if the two indexes exist in the character array
if(chars[indexes[0]] && chars[indexes[1]]){
// add the tag into each index
chars.splice(indexes[0],0,"<span>");
chars.splice(indexes[1],0,"</span>");
}
}
// return the joined string
return chars.join('');
}
就个人而言,我喜欢字符串替换解决方案,但如果你不想要一个,这可能会起作用
答案 3 :(得分:1)
首先,你想要向后迭代,以确保你最终不会覆盖之前所做的替换,但是,在我的例子中它并不重要,因为字符串在最后一次被重新组装
// > interpolateOnIndices([[5,9], [23,27]], "eggs eggs spam and ham spam");
// < 'eggs <span>eggs</span> spam and ham <span>spam</span>'
function interpolateOnIndices(indices, string) {
"use strict";
var i, pair, position = string.length,
len = indices.length - 1, buffer = [];
for (i = len; i >= 0; i -= 1) {
pair = indices[i];
buffer.unshift("<span>",
string.substring(pair[0], pair[1]),
"</span>",
string.substring(pair[1], position));
position = pair[0];
}
buffer.unshift(string.substr(0, position));
return buffer.join("");
}
这比使用splice
的示例稍好一些,因为它不会创建额外的数组(splice本身会创建其他数组)。在其他函数中重复使用映射和创建函数是一定的内存耗尽,但它运行得不是很快......虽然它有点短。
理论上,在大型字符串连接时,应该优先于多个连接,因为内存分配将进行一次,而不是随后丢弃一个半生不熟的字符串。当然,除非您正在处理大量数据,否则所有这些都不需要关注您。
修改强>
因为我手上有太多时间,所以我决定进行一项测试,看看变量将如何在更大(但相当实际)的数据集上进行比较,下面是我的测试代码,其中包含一些结果... < / p>
function interpolateOnIndices(indices, string) {
"use strict";
var i, pair, position = string.length,
len = indices.length - 1, buffer = [];
for (i = len; i >= 0; i -= 1) {
pair = indices[i];
buffer.unshift("<span>",
string.substring(pair[0], pair[1]),
"</span>",
string.substring(pair[1], position));
position = pair[0];
}
buffer.unshift(string.substr(0, position));
return buffer.join("");
}
function indexWrap(indexArr, str) {
var chars = str.split("");
for(var i = 0; i < indexArr.length; i++) {
var indexes = indexArr[i];
if(chars[indexes[0]] && chars[indexes[1]]){
chars.splice(indexes[0], 0, "<span>");
chars.splice(indexes[1], 0, "</span>");
}
}
return chars.join("");
}
function replaceOffset(str, offs, tag) {
tag = tag || "span";
offs.reverse().forEach(
function(v) {
str = str.replace(
new RegExp("(.{" + v[0] + "})(.{" + (v[1] - v[0]) + "})"),
"$1<" + tag + ">$2</" + tag + ">"
);
});
return str;
}
function generateLongString(pattern, times) {
"use strict";
var buffer = new Array(times);
while (times >= 0) {
buffer[times] = pattern;
times -= 1;
}
return buffer.join("");
}
function generateIndices(pattern, times, step) {
"use strict";
var buffer = pattern.concat(), block = pattern.concat();
while (times >= 0) {
block = block.concat();
block[0] += step;
block[1] += step;
buffer = buffer.concat(block);
times -= 1;
}
return buffer;
}
var longString = generateLongString("eggs eggs spam and ham spam", 100);
var indices = generateIndices([[5,9], [23,27]], 100,
"eggs eggs spam and ham spam".length);
function speedTest(thunk, times) {
"use strict";
var start = new Date();
while (times >= 0) {
thunk();
times -= 1;
}
return new Date() - start;
}
speedTest(
function() {
replaceOffset(longString, indices, "span"); },
100); // 1926
speedTest(
function() {
indexWrap(indices, longString); },
100); // 559
speedTest(
function() {
interpolateOnIndices(indices, longString); },
100); // 16
在amd64 Linux(FC-17)上针对V8(Node.js)进行了测试。
我没有测试undefined的答案,因为我不想加载那个库,特别是因为它没有对这个测试做任何有用的事情。我想它会在两个人之间以及elclanrs的变体之间徘徊,更多的是对elclanrs的回答。
答案 4 :(得分:0)
您可以使用子字符串方法 String.substring(startIndex,endIndex); description:在start&amp;之间返回字符串。结束指数 用法:
var source="hello world";
var result=source.substring (3,7); //returns 'lo wo'
你已经有了一个带有初始&amp;的数组。最终索引,所以你差不多完成了:)