Regex ссылки на захваченные группы - PullRequest
0 голосов
/ 17 октября 2019

Во-первых, я очень новичок в Regex, поэтому приношу свои извинения, если это глупый вопрос.

Я просто использую онлайн-тестер Regex https://regex101.com (PCRE) для построения следующегосценарий.

Я хочу захватить 123445 и ABC1234 из следующего предложения

Foo Bar 123445 Ref ABC1234

Я просто хотел использовать простую группу захвата

((?:\w)+)

Который идентифицирует 5 совпадающих групп. И тогда я мог бы сослаться на него с $3 и $5

Однако, когда я пытаюсь использовать Подстановку только с одной группой,$3, я получаю всю строку. Я попробовал некоторые другие языки и в итоге получил

$3 $3 $3 $3 $3

В конце я просто использовал Foo\s*Bar\s*(\w+)\s*Ref\s*(\w+) и ссылки на группы $1 и $2, которые работают нормально, но простоне очень элегантно.

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

Спасибо:)

Ответы [ 2 ]

1 голос
/ 17 октября 2019

((?: \ W) +)

, который идентифицирует 5 подходящих групп. И тогда я мог бы сослаться на него с $ 3 и $ 5

Нет, этоне так, как работают обратные ссылки. В регулярном выражении содержится ровно N групп, а N - это число открывающих скобок.

В ((?:\w)+) есть 2 группы: одна "захват" (которая создает обратную ссылку) и одна "не захват"(чего нет).

Количество совпадений группы в целевой строке не меняет количество обратных ссылок. Вообразите хаос, который это создаст. За исключением самых упрощенных случаев, как вы узнаете, что вы ищете $3, $9 или $9000?

Если ваша входная строка имеет фиксированную структуру, то ваш подходFoo\s*Bar\s*(\w+)\s*Ref\s*(\w+) с $1 и $2 прекрасно.


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

Нет. Вы должны создать одну группу захвата для каждой части, к которой вы пытаетесь обратиться. Если группа совпадает несколько раз, вы получите последний экземпляр каждого совпадения во входных данных.

Некоторые движки регулярных выражений позволяют вам получить доступ к каждому экземпляру того, что определенная группа захватила с основного языка. Например, .NET regex engine делает это . Это хорошо для постобработки, но обратные ссылки сами (т.е. $1) по-прежнему работают, как указано выше.


Все это, как говорится, способ получить '123445' и 'ABC1234' из Foo Bar 123445 Ref ABC1234 в том смысле, в каком вы думали, - избегать регулярных выражений и string.split() в пространстве, взяв части 2 и 3.

0 голосов
/ 17 октября 2019

Не совсем понятно, что вы пытаетесь сопоставить и что вы хотите заменить, основываясь на вашем вопросе.

В целях получения ответа для вас я собираюсьПредположим, что вы хотите сопоставить любое слово, имеющее номер, и заменить его чем-то другим.

\w*?\d+\w*? будет сопоставлять любое слово с цифрой в нем и с JavaScript (вы не делалине указывать язык), вы выполняете ручную или динамическую замену с помощью функции replacer .

const expression = /\b(\w*?\d+\w*?)\b/g;
const inputs = [
  'Foo Bar 123445 Ref ABC1234',
  'Hello World 123 Foo ABC123XYZ456'
];

// static string
console.log(inputs.map(i => i.replace(expression, '**redacted**')));

// dynamic string
console.log(inputs.map(i => i.replace(expression, s => new Array(s.length).fill('*').join(''))));
...