Регулярное выражение js не захватывает

Я пытаюсь написать регулярное выражение javascript. То, что я написал до сих пор,

function getName(text) {
    var r = /(.*) \(\d+\)/.exec(text);
    if (r && r.length>1) {
        return r[1];
    } else {
        return "";
    }
}

Текст имеет формат

Name (possibly containing spaces) followed by a space followed by open parens followed by a number followed by a close parens followed by more text that I don't care about.

Пример

foo bar (123) 1.1/2.2 3.3%

Я пробовал приведенный выше код в нескольких онлайн-тестерах регулярных выражений (regex101.com и regexr.com), и он работает так, как я ожидал, т. Е. Соответствует до rparen включительно и захватывает до, но не включая пространство перед lparen.

При запуске в Firefox совпадением является только родительский номер-пробел-lparen-number-r, а захват пуст. Я попытался добавить флаги gm и поставить якорь ^, но безрезультатно.

При захвате будет получено все, что до номера в скобках ("foo bar"). Что вы ожидаете?

Pointy 10.08.2018 15:01

@Pointy Он хочет записать число в скобках.

Ryan Wilson 10.08.2018 15:03

Пример обновлен, и нет, я не хочу захватывать внутри скобок. Это текст на пробел перед lparen, который я хочу захватить.

Paul Floyd 10.08.2018 15:06

Хорошо, что является работает в Firefox. Что заставляет вас думать, что это не так? Я только что сделал это в консоли разработчика, и в массиве результатов есть вся строка в элементе 0 и «foo bar» в элементе 1.

Pointy 10.08.2018 15:30

В частности, я набрал /^(.*) \(\d+\)/.exec("foo bar (123)") и получил описанный мной массив.

Pointy 10.08.2018 15:32

У меня также работает, когда я вставляю его напрямую в веб-консоль.

Paul Floyd 10.08.2018 15:47
1
6
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Кажется, ваше регулярное выражение работает нормально, я пробовал Firefox 61, Chrome 68, IE11 и Edge, и все они работали нормально. Мне кажется, что среда выполнения, которую вы используете, не поддерживает регулярные выражения должным образом.

Вот что я тестировал:

/^(.*) \(\d+\)/

Итак, сначала ^, затем захватите все (.*), затем пробел , затем вы выходите из скобок, открывая \(, сопоставляя все цифры в нем \d+ и, наконец, избегайте закрывающих скобок \).

Пример использования:

foo bar (123)

[
  "foo bar (123)", // the whole match ^(.*) \(\d+\)/
  "foo bar",       // first capture group (.*)
]

Запустите приведенный ниже фрагмент, чтобы проверить.

var r = /^(.*) \(\d+\)/.exec('foo bar (123)');

console.log(r);

Note on OP's answer: To complement @PaulFloyd's answer, you can use \s+ to capture invisible char so that with this regex ^(.*)\s+\(\d+\) you can achieve your goal even if there is a extra \n with the space.

Хороший ответ, но это не моя проблема. Я хочу записать «foo bar», но не понимаю, почему он не работает в Firefox.

Paul Floyd 10.08.2018 15:28

хм @PaulFloyd какую версию вы используете? Запустив сниппет, вы получили [ "foo bar (123)", "foo bar", "123" ]? Кстати, я использую firefox (последний)

lenilsondc 10.08.2018 15:32

На моем рабочем столе (во Франции, набираю это) я запускаю последнюю версию Windows Opera (54.0). Для своей разработки (в Калифорнии через Citrix на Linux) я использую FF 44.0.2 и 55.2.1). Если я загружаю эту страницу в FF, я получаю сообщение об ошибке, что stacksnippets.net не может быть найден.

Paul Floyd 10.08.2018 15:41

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

lenilsondc 10.08.2018 15:59

Я попробую, но это означает борьбу с брандмауэром, поэтому я обычно все делаю через Citrix.

Paul Floyd 10.08.2018 16:01
Ответ принят как подходящий

Я нашел проблему. Я видел это с помощью отладчика Opera (думаю, Chrome тоже справился бы с этой задачей).

Исходная строка читается из файла, и была новая строка, которая не была обрезана, поэтому вводимый текст действительно был

foo bar\n (123) other stuff

Зная это, захватываю и соответствую тому, что я ожидал.

(Отладчик Opera показал встроенную новую строку).

Чтобы дополнить свой ответ, вы можете использовать \s+ для захвата невидимого символа, чтобы с этим регулярным выражением ^(.*)\s+\(\d+\) вы могли достичь своей цели.

lenilsondc 10.08.2018 18:14

Другие вопросы по теме