Регулярное выражение, которое позволяет шаблону начинаться с необязательного, указанного c символа, но без другого символа - PullRequest
0 голосов
/ 25 марта 2020

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

Например, я хотел бы сопоставить все вхождения слова "привет" «где« привет »либо в самом начале строки, либо перед ним стоит«! », и в этом случае он не обязательно должен быть в начале строки. Таким образом, первые три варианта здесь должны совпадать, но не последний:

hello
!hello
some other text !hello more text
ahello

Меня особенно интересует JavaScript.

Ответы [ 2 ]

2 голосов
/ 25 марта 2020

Сопоставьте его с: /^hello|!hello/g

^ будет захватывать слово "привет", только если оно находится в начале строки.

| работает как ИЛИ.

var str = "hello\n!hello\n\nsome other text !hello more text\nahello";

var regex = /^hello|!hello/g;

console.log( str.match(regex) );

Редактировать:

Если вы пытаетесь сопоставить всю строку, начинающуюся с «hello» или содержащую «! Hello» как предложено в комментарии ниже, затем используйте следующее регулярное выражение:

/^.*(^hello|!hello).*$/gm

var str = "hello\n!hello\n\nsome other text !hello more text\nahello";

var regex = /^.*(^hello|!hello).*$/gm;

console.log(str.match(regex));
1 голос
/ 25 марта 2020

Окончательное решение (надеюсь)

Похоже, что groups доступно только в ECMAScript 2020. Ссылка 1 , Ссылка 2 .

В качестве обходного пути я нашел следующее решение:

const str = `hello
!hello
some other text !hello more text
ahello
this is a test hello !hello
JvdV is saying hello
helloing or helloed =).`;

function collectGroups(regExp, str) {
  const groups = [];
  str.replace(regExp, (fullMatch, group1, group2) => {
    groups.push(group1 || group2);
  });
  return groups;
}
const regex = /^(hello)|(?:!)(hello\b)/g;
const groups = collectGroups(regex, str)
console.log(groups)

/(?=!)?(\bhello\b)/g должен это сделать. Детская площадка .

Пример:

const regexp = /(?=!)?(\bhello\b)/g;

const str = `
hello
!hello
some other text !hello more text
ahello
`;

const found = str.match(regexp)

console.log(found)

Объяснение:

  • (?=!)?

    • (?=!) положительный прогноз для !
    • ? ! необязательно
  • (\bhello\b): группа захвата

    • \b граница слова гарантирует, что привет не будет предшествовать или следовать за ним символ

Примечание. Если вы также убедитесь, что hello не должен заменяться ! , тогда вы можете просто добавить отрицательный взгляд, например, так: /(?=!)?(\bhello\b)(?!!)/g.


Обновление

Благодаря подсказке @JvdV в комментарии я теперь адаптировал регулярное выражение, которое должно соответствовать вашим требованиям:

/(^hello\b)|(?:!)(hello\b)/gm

Детская площадка: https://regex101.com/r/CXXPHK/4 ( Объяснение также можно найти на странице).


Обновление 2:

Похоже, группа без захвата (?:!) не работает ну в JavaScript, то есть я получаю соответствующий результат как ["hello", "!hello", "!hello", "!hello"], где также включено ! , Но кого это волнует, вот обходной путь:

const regex = /(^hello\b)|(?:!)(hello\b)/gm;
const found = (str.match(regex) || []).map(m => m.replace(/^!/, ''));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...