Выполнение этого с использованием только RegExes не рекомендуется, хотя это, безусловно, возможно в некоторых реализациях, возможно, даже в JavaScript. Язык, который вы описываете, не является регулярным, и RegExes, таким образом, не являются лучшим решением этой проблемы (хотя не регулярные языки могут быть проанализированы с дополнениями, такими как lookaheads/-behinds, balancing groups, recursion и т. Д.). Однако 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 не всегда являются лучшим решением, и этот вид кода будет масштабироваться до более сложных правил и проблем. И это, вероятно, тоже быстрее. Я следую основным принципам проектирования компилятора здесь (стресс на basic). Это берет входной поток и переводит его в список токенов: ors, другие слова, пробелы и кавычки. Затем он потребляет эти жетоны один за другим и отправляет соответствующий код для каждого вида токена, который затем генерирует соответствующий вывод.
Невозможно сделать это только с RegEx, вам понадобятся lookbehinds, которые пока не поддерживаются. :( –
@ElliotBonneville, видимо, вы ошибаетесь;) – brandonscript