2014-01-29 4 views
0
var a = 'New York or "United States or Canada" OR "England or France" Or Mexico'; 

Я хочу, чтобы массив, который походит на следующее:Regular Expression цитат

var b = ['New York','United States or Canada', 'England or France', 'Mexico']; 

В принципе, должен разделить весь ОШ для тех, между кавычками, за исключением.

Мне нужно сделать это в Javascript, я не могу заставить регулярное выражение работать отлично. Возможно ли это сделать, используя только Regex или мне придется использовать Regex + некоторую логику JavaScript, чтобы заставить ее работать.

+1

Невозможно сделать это только с RegEx, вам понадобятся lookbehinds, которые пока не поддерживаются. :( –

+0

@ElliotBonneville, видимо, вы ошибаетесь;) – brandonscript

ответ

4

Попробуйте

var b = a.split(/\s+or\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/i) 
+0

Yup it works. Однако те, у которых есть котировки, имеют котировки (т. Е. Вторая запись показывает как «Соединенные Штаты или Канада», а не «Соединенные Штаты или Канада») – user3241857

1

Это проще всего использовать PHP взрываются функцию, чтобы разделить массив на «ИЛИ» s, если вы можете использовать PHP. Однако, если вы должны использовать только Javascript, попробуйте что-то вроде рекомендуемого выше администратора.

0

хорошо, самый простой способ, было бы «заставить» положить кавычки вокруг каждой группы:

var a = '"New York" or "United States or Canada" OR "England or France" Or "Mexico"'; 
var out = a.replace("OR", "or").replace("Or", "or").split('" or "') 
[ '"New York', 
    'United States or Canada', 
    'England or France', 
    'Mexico"' ] 

, но вы можете рассмотреть это как-то обман.

0

Выполнение этого с использованием только 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, другие слова, пробелы и кавычки. Затем он потребляет эти жетоны один за другим и отправляет соответствующий код для каждого вида токена, который затем генерирует соответствующий вывод.