3

好吧,这个标题很吸引人。我会承认的。现在问题来了!

概述 我在一个项目中有一些代码,我正在处理带有 HTML 标记的标记文本(用于 Flash wiki)。我创建了一个独立的文件,我将在这个问题中重点关注它,以使事情更清楚。

我想做什么 我的输入是一个关键字列表和一个文本块。在这种情况下,输入是

["panda","tea","tea cup","panda tea cup"];

"Tea is good. I like tea cups, too. Pandas also like tea but need special panda tea cups to drink it.";

预期的输出应该是这样的:

"<Tea> is good. I like <tea cups>, too. <Panda>s also like <tea> but need special <panda tea cups> to drink it.

问题我以为我可以用一个简单的 replace() 函数来做到这一点,但很快意识到我最终会得到这个:

"<Tea> is good. I like <<tea> cups>, too. <Panda>s also like <tea> but need special <<panda> <<tea> cups>> to drink it."

这是我不想要的。

我最终决定构建一个递归函数,将代码从最长的关键字开始分解到最小的关键字。虽然现在我完全糊涂了并且不断收到 recursiveParse 错误。

完整代码

//Setup
var kw:Array = ["panda","tea","tea cup","panda tea cup"];
var s:String = "Tea is good. I like tea cups, too. Pandas also like tea but need special panda tea cups to drink it.";
var openTag:String = "<<";
var closeTag:String = ">>";
var tS:Array = [];
//Sort by length (longest to shortest)
for (var i:int = 0; i<kw.length; i++) {
    for (var j:int = kw.length - 1; j > i; j--) {
        if (kw[j - 1].length < kw[j].length) {
            var temp:String = kw[j - 1];
            kw[j - 1] = kw[j];
            kw[j] = temp;
        }
    }
}
//Parse
tS[0] = s;
s = recursiveParse(s);
var n:int = 0;
function recursiveParse(m:String) {
    var tP = kw[n];
    if (m.length == 0) {
        return "test";
    }
    var p:RegExp = new RegExp(tP,"gi");
    m = m.replace(p,openTag + "$&" + closeTag);
    tP = "[<>]";
    p = new RegExp(tP);
    var b:Array = m.split(p);
    var fI:String = "";
    n++;
    for each (var f in b) {
        if (f.length > 0) {
            tS[tS.length] = recursiveParse(f);
        }
    }
    return fI;
}
trace(s);

提前感谢您的出色回答!请记住,我在任何程度上都不关心上面的代码。如果您的答案是对代码进行简单的三行修复,或者您自己的 33 行代码不考虑我的工作,那我很好。只要输入变成输出。

更新:好的,我现在意识到 stackoverflow 隐藏了我的尖括号。必须解决这个问题。更新:固定尖括号。

4

1 回答 1

6

好吧,您不需要使用递归。首先,确保您的数组中搜索的字符串按复杂度递减顺序排列:

var kw:Array = ["panda tea cup","tea cup","panda","tea"];

也就是说,如果字符串 A 包含字符串 B,那么 A 必须先出现。然后,您可以使用此正则表达式:/(panda tea cups|tea cups|tea|panda)/i或者,在您的情况下,执行:

var p:RegExp = new RegExp("("+kw.join("|")+")","gi");

并用 替换匹配项<$&>,就像现在一样。

您可以在此处查看此正则表达式。

于 2012-09-11T16:16:10.667 回答