這樣做只使用RegExes是不可取的,儘管它在某些實現中可能甚至可能是JavaScript。你描述的語言不是經常性的,因此RegExes不是解決這個問題的最佳解決方案(儘管非常規語言可以用諸如lookaheads/-behinds,平衡組,遞歸等的附加語法來解析。 RegExes可能會幫助實現這樣的解析器。下面的代碼應該做你想做的。
function splitOnOr(str) {
var patterns, pos, res, tokens, inQuotes;
patterns = [
{ name: "or", expr: /^\s+or\s+/i },
{ name: "words", expr: /^\w+/ },
{ name: "whitespace", expr: /^\s+/ },
{ name: "quote", expr: /^"/ }
];
pos = 0;
res = [""];
tokens = [];
inQuotes = false;
while (pos < str.length) {
for (i = 0; i < patterns.length; ++i) {
m = patterns[i].expr.exec(str.substr(pos));
if (m) {
pos += m[0].length;
tokens.push({type: patterns[i].name, payload: m[0]});
}
}
}
for (i = 0; i < tokens.length; ++i) {
switch (tokens[i].name) {
case "quote":
inQuotes = !inQuotes;
break;
case "or":
if (!inQuotes) {
res.push("");
break;
}
case default:
res[res.length-1] += tokens[i].payload;
}
}
return res;
}
這是否矯枉過正?是的,但我試圖闡明一些觀點並在此展示一些最佳實踐:RegExes並不總是最好的解決方案,這種代碼將擴展爲更復雜的規則和問題。它也可能更快。我在這裏遵循編譯器設計的基本原則(強調基本爲)。這需要輸入流並將其指定爲令牌列表:ors,其他詞,空格和引號。然後它會逐個使用這些令牌,併爲每種令牌分配相應的代碼,然後生成相應的輸出。
無法僅通過RegEx執行此操作,您需要lookbehinds,目前尚不支持。 :( –
@ElliotBonneville顯然你錯了;) – brandonscript