我允许我的用户将带有“*”,“/”,“_”和“ - ”的单词换行,作为表示他们想要粗体,斜体,下划线或删除其文本的简写方式。不幸的是,当页面使用此标记填充文本时,我看到一个明显的(可接受的边界线)减速。
这是我为处理此任务而编写的JavaScript。你能否就我如何加快速度提供反馈?
function handleContentFormatting(content) {
content = handleLineBreaks(content);
var bold_object = {'regex': /\*(.|\n)+?\*/i, 'open': '<b>', 'close': '</b>'};
var italic_object = {'regex': /\/(?!\D>|>)(.|\n)+?\//i, 'open': '<i>', 'close': '</i>'};
var underline_object = {'regex': /\_(.|\n)+?\_/i, 'open': '<u>', 'close': '</u>'};
var strikethrough_object = {'regex': /\-(.|\n)+?\-/i, 'open': '<del>', 'close': '</del>'};
var format_objects = [bold_object, italic_object, underline_object, strikethrough_object];
for( obj in format_objects ) {
content = handleTextFormatIndicators(content, format_objects[obj]);
}
return content;
}
//@param obj --- an object with 3 properties:
// 1.) the regex to search with
// 2.) the opening HTML tag that will replace the opening format indicator
// 3.) the closing HTML tag that will replace the closing format indicator
function handleTextFormatIndicators(content, obj) {
while(content.search(obj.regex) > -1) {
var matches = content.match(obj.regex);
if( matches && matches.length > 0) {
var new_segment = obj.open + matches[0].slice(1,matches[0].length-1) + obj.close;
content = content.replace(matches[0],new_segment);
}
}
return content;
}
答案 0 :(得分:1)
您的代码强制浏览器执行大量重复,浪费的工作。你应该采取的方法是:
至于如何组合正则表达式,嗯,它在JavaScript中不是很漂亮,但它看起来像这样。首先,你需要一个零或更多“无趣”字符串的正则表达式。这应该是正则表达式中的第一个捕获组。接下来应该是您正在寻找的目标字符串的替代项。因此,一般形式是:
var tokenizer = /(uninteresting pattern)?(?:(target 1)|(target 2)|(target 3)| ... )?/;
当您将其与源字符串匹配时,您将返回包含以下内容的结果数组:
result[0] - entire chunk of string (not used)
result[1] - run of uninteresting characters
result[2] - either an instance of target type 1, or null
result[3] - either an instance of target type 2, or null
...
因此,您可以通过检查哪些目标正则表达式非空来了解您看到的替换目标。 (请注意,在您的情况下,目标可以想象重叠;如果您打算使用它,那么您将不得不将其视为我怀疑的完整解析问题。)
答案 1 :(得分:1)
使用标记/ig
更改正则表达式并删除while循环。
使用正常for循环更改for(obj in format_objects)
循环,因为format_objects
是一个数组。
好的,我花时间根据您的代码编写了一个更快速,更简化的解决方案:
function handleContentFormatting(content) {
content = handleLineBreaks(content);
var bold_object = {'regex': /\*([^*]+)\*/ig, 'replace': '<b>$1</b>'},
italic_object = {'regex': /\/(?!\D>|>)([^\/]+)\//ig, 'replace': '<i>$1</i>'},
underline_object = {'regex': /\_([^_]+)\_/ig, 'replace': '<u>$1</u>'},
strikethrough_object = {'regex': /\-([^-]+)\-/ig, 'replace': '<del>$1</del>'};
var format_objects = [bold_object, italic_object, underline_object, strikethrough_object],
i = 0, foObjSize = format_objects.length;
for( i; i < foObjSize; i++ ) {
content = handleTextFormatIndicators(content, format_objects[i]);
}
return content;
}
//@param obj --- an object with 2 properties:
// 1.) the regex to search with
// 2.) the replace string
function handleTextFormatIndicators(content, obj) {
return content.replace(obj.regex, obj.replace);
}
这适用于嵌套和/或不嵌套的格式边界。如果您愿意,可以完全省略函数handleTextFormatIndicators
,并在handleContentFormatting
内部进行内联替换。
答案 2 :(得分:1)
您可以执行以下操作:
function formatText(text){
return text.replace(
/\*([^*]*)\*|\/([^\/]*)\/|_([^_]*)_|-([^-]*)-/gi,
function(m, tb, ti, tu, ts){
if(typeof(tb) != 'undefined')
return '<b>' + formatText(tb) + '</b>';
if(typeof(ti) != 'undefined')
return '<i>' + formatText(ti) + '</i>';
if(typeof(tu) != 'undefined')
return '<u>' + formatText(tu) + '</u>';
if(typeof(ts) != 'undefined')
return '<del>' + formatText(ts) + '</del>';
return 'ERR('+m+')';
}
);
}
这适用于嵌套标签,但不会使用重叠标签,无论如何都是无效的。
的示例