Регулярное выражение для сопоставления строки, содержащей два имени в любом порядке

180

Мне нужно логическое И в регулярных выражениях.

что-то вроде

Джек и Джеймс

согласен со следующими строками

  • «Привет, Джек, вот Джеймс »

  • «Привет, Джеймс, это Джек »

Мэлоун
источник
1
Возможные дубликаты: регулярные выражения "несколько слов в любом порядке"
Андерсон Грин,
@AndersonGreen, вопрос был преждевременно заблокирован. Ответы крайне отсутствуют, так как эти решения нежизнеспособны, так как большинство регулярных выражений не распознают обходной и модовый квантификаторы . Я считаю, что квантификатор существовал в момент задаваемого вопроса.
XPMai

Ответы:

261

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

^(?=.*\bjack\b)(?=.*\bjames\b).*$

Попробуй это.

Этот подход имеет то преимущество, что вы можете легко указать несколько условий.

^(?=.*\bjack\b)(?=.*\bjames\b)(?=.*\bjason\b)(?=.*\bjules\b).*$
Алин Пуркару
источник
18
Не возражает ли кто-нибудь объяснить более подробно, как работает этот пример?
BJMC
2
vimсинтаксис: ^\(.*\<jack\>\)\@=\(.*\<james\>\@=\).*$или\v^(.*<jack>)@=(.*<james>)@=.*$
mykhal
Кто-нибудь знает, почему это может прерваться (по крайней мере, в JavaScript), когда я пытаюсь найти строки, начинающиеся с '#'? ^(?=.*\b#friday\b)(?=.*\b#tgif\b).*$не соответствует, blah #tgif blah #friday blahно ^(?=.*\bfriday\b)(?=.*\btgif\b).*$работает нормально.
блефлер
2
Что \bзначит здесь?
VarunAgw
1
@VarunAgw Граница слова . normal-expressions.info/refwordboundaries.html
Алин Пуркару
107

Пытаться:

james.*jack

Если вы хотите оба одновременно, то orих:

james.*jack|jack.*james
icyrock.com
источник
1
Принятый ответ сработал. это также отлично сработало для меня. Для поиска кода в визуальной студии «найти результаты».
Йогурт Мудрый
1
Этот работает для меня и является намного более кратким и легким для понимания, чем принятый ответ!
Кумар Маниш
1
Мне нужно было решение, в котором должны были совпадать только два имени, поэтому этот ответ является более кратким для этого случая. Но принятый ответ становится более кратким за пределами 2, так как число «или» увеличивается факториально. Для 3 имен будет 6 "или" s, 4 имени будет 24 "или" s, и т. Д.
WileCau
Я бы порекомендовал сделать это ленивым james.*?jack|jack.*?james. Это поможет на больших текстах.
Джекис
42

Объяснение команды, которую я собираюсь написать : -

. означает любой символ, цифра может прийти вместо.

* означает ноль или более вхождений вещи, написанной как раз перед ней.

|означает «или» .

Так,

james.*jack

будет искать james , то любое количество символов, пока не jackпридет.

Так как вы хотите jack.*jamesилиjames.*jack

Отсюда и команда :

jack.*james|james.*jack
Шубхам Шарма
источник
7
В качестве примечания: вы могли бы также отредактировать ответ @ icyrock (который совпадает с вашим, всего 6 лет назад), ваше объяснение само по себе очень полезно.
WoJ
2
Спасибо за этот ответ, однако я чувствую необходимость указать, что в поиске VSCode ваш ответ jack. * James | Джеймс. * Джек займет пробел между '|' (или) символ учитывается при поиске. Джек. * Джеймс | Джеймс. * Джек работает и не ищет пробелы
jgritten
2
ЕСЛИ $ _explanation === "круто", ТО вернуть $ THUMBS_UP ENDIF;
Сайед Аквил
9

Его короткая и сладкая

(?=.*jack)(?=.*james)
Шивам Агравал
источник
6

Ты можешь сделать:

\bjack\b.*\bjames\b|\bjames\b.*\bjack\b
codaddict
источник
2

В Vim есть оператор ветвления, \&который полезен при поиске строки, содержащей набор слов в любом порядке. Более того, расширение набора необходимых слов тривиально.

Например,

/.*jack\&.*james

будет соответствовать строке, содержащей jackи james, в любом порядке.

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

Firstrock
источник
2

МЕТОД 1: Один jackи Одинjames

На всякий случай, если два jackили два jamesне будут разрешены, допустимы только один jackи один james, мы можем разработать выражение, подобное:

^(?!.*\bjack\b.*\bjack\b)(?!.*\bjames\b.*\bjames\b)(?=.*\bjames\b)(?=.*\bjack\b).*$

Здесь мы исключили бы эти пару экземпляров, используя эти операторы:

(?!.*\bjack\b.*\bjack\b)

и,

(?!.*\bjames\b.*\bjames\b)

RegEx Demo 1

Мы также можем упростить это,

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$

RegEx Demo 2


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


RegEx Circuit

jex.im визуализирует регулярные выражения:

введите описание изображения здесь

Тест

const regex = /^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$/gm;
const str = `hi jack here is james
hi james here is jack
hi james jack here is jack james
hi jack james here is james jack
hi jack jack here is jack james
hi james james here is james jack
hi jack jack jack here is james
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}


МЕТОД 2: Один jackи Один jamesв определенном порядке

Это может также быть разработано для первого jamesпоследнего jack, подобного следующему:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b.*\bjack\b).*$

RegEx Demo 3

и наоборот:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjack\b.*\bjames\b).*$

RegEx Demo 4

Эмма
источник
0

Вы можете использовать функцию квантификатора регулярных выражений, поскольку она lookaroundможет поддерживаться не всегда.

(\b(james|jack)\b.*){2,}
XPMai
источник