Потерянный в переводе - регулярное выражение C # в JavaScript регулярное выражение - PullRequest
5 голосов
/ 05 мая 2010

У меня возникли проблемы с переводом моего рабочего регулярного выражения C # в реализацию регулярного выражения JavaScript.

Вот регулярное выражение:

([a-z]+)((\d+)([a-z]+))?,?

При использовании на "water2cups,flour4cups,salt2teaspoon" вы должны получить:

[
    ["water", "2cups", "2", "cups"]
    ["flout", "4cups", "4", "cups"]
    ["salt", "2teaspoon", "2", "teaspoon"]
]

... И это так. В C #. Но не в JavaScript.

Я знаю, что есть некоторые незначительные различия между реализациями. Чего мне не хватает, чтобы заставить это выражение работать в JavaScript?

Обновление

Я использую регулярное выражение так:

"water2cups,flour4cups,salt2teaspoon".match(/([a-z]+)((\d+)([a-z]+))?,?/g);

Ответы [ 2 ]

12 голосов
/ 05 мая 2010

Создание RegExp

Вы не показали как вы создаете регулярное выражение Javascript, например, используете ли вы литерал:

var rex = /([a-z]+)((\d+)([a-z]+))?,?/;

или строка

var rex = new RegExp("([a-z]+)((\\d+)([a-z]+))?,?");

Если последнее, обратите внимание, что я избежал обратной косой черты.

Глобальный флаг

По умолчанию регулярные выражения Javascript не являются глобальными, что может быть проблемой для вас. Добавьте флаг g, если у вас его еще нет:

var rex = /([a-z]+)((\d+)([a-z]+))?,?/g;

или

var rex = new RegExp("([a-z]+)((\\d+)([a-z]+))?,?", "g");

Использование RegExp#exec вместо String#match

Ваше редактирование говорит, что вы используете String#match, чтобы получить массив совпадений. Я должен признать, что почти никогда не использую String#match (я использую RegExp#exec, как показано ниже.) Когда я использую String#match с вашим регулярным выражением, я получаю ... очень странные результаты, которые варьируются от браузера к браузеру. Использование цикла RegExp#exec этого не делает, поэтому я бы так и сделал.

Рабочий пример

Этот код делает то, что вы ищете:

var rex, str, match, index;

rex = /([a-z]+)((\d+)([a-z]+))?,?/g;
str = "water2cups,flour4cups,salt2teaspoon";

rex.lastIndex = 0; // Workaround for bug/issue in some implementations (they cache literal regexes and don't reset the index for you)
while (match = rex.exec(str)) {
    log("Matched:");
    for (index = 0; index < match.length; ++index) {
        log("&nbsp;&nbsp;match[" + index + "]: |" + match[index] + "|");
    }
}

(Функция log просто добавляет текст в div.)

Мой вывод для этого:

Matched:
  match[0]: |water2cups,|
  match[1]: |water|
  match[2]: |2cups|
  match[3]: |2|
  match[4]: |cups|
Matched:
  match[0]: |flour4cups,|
  match[1]: |flour|
  match[2]: |4cups|
  match[3]: |4|
  match[4]: |cups|
Matched:
  match[0]: |salt2teaspoon|
  match[1]: |salt|
  match[2]: |2teaspoon|
  match[3]: |2|
  match[4]: |teaspoon|

(Напомним, что в Javascript match[0] будет целым совпадением; затем match[1] и т. Д. - ваши группы захвата.)

0 голосов
/ 05 мая 2010

C # имеет оператор "@", который автоматически экранирует обратную косую черту (). Я не думаю, что Javascript поддерживает его, поэтому вам, по сути, нужно «убрать» обратную косую черту, вставив другую, так что это должно сработать

([a-z]+)((\d+)([a-z]+))?,?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...