Regex відповідає рядку, що містить два імені в будь-якому порядку


180

Мені потрібні логічні І в регулярних виразах.

щось на зразок

джек І джеймс

погоджуються з наступними рядками

  • "привіт Джек ось Джеймс "

  • "привіт Джеймс, ось Джек "


1
Можливий дублікат: mulitple-words-in-any-order-using-regex
Anderson Green

@AndersonGreen, питання було передчасно заблоковано. Відповідей вкрай не вистачає, оскільки ці рішення не є життєздатними, оскільки більшість регулярних виразів не розпізнають кількісний коефіцієнт орієнтації та режиму . Я вважаю, що кількісний показник існував на момент запитання.
XPMai

Відповіді:


261

Ви можете робити перевірки за допомогою lookarounds :

^(?=.*\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).*$працює чудово.
btleffler

2
Що \bтут означає?
VarunAgw


106

Спробуйте:

james.*jack

Якщо ви хочете обох одночасно, то orїх:

james.*jack|jack.*james

1
Прийнята відповідь спрацювала. це також прекрасно працювало для мене. Для пошуку коду у візуальній студії "знайти результати".
Йогурт Мудрий

1
Цей для мене працює і набагато більш лаконічний і легкий для розуміння, ніж прийнята відповідь!
Кумар Маніш

1
Мені було потрібно рішення, яке має відповідати лише двом іменам, тому ця відповідь є більш стислим для цього випадку. Але прийнята відповідь стає більш короткою за рамки 2, оскільки кількість "або" s фактично збільшується. Для 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 ваш джек- відповідь . * James | james. * jack займе проміжки між знаками '|' (або) символ, який слід враховувати під час пошуку. jack. * james | james. * jack працює і не шукає простору
jgritten

2
ЯКЩО $ _explanation === "awesome" ТАКІ поверніть $ THUMBS_UP ENDIF;
Syed Aqeel



2

Vim має оператора філії \& який корисний при пошуку рядка, що містить набір слів, у будь-якому порядку. Більше того, розширення набору необхідних слів є тривіальним.

Наприклад,

/.*jack\&.*james

буде відповідати рядку, що містить jackі jamesв будь-якому порядку.

Дивіться цю відповідь для отримання додаткової інформації про використання. Мені не відомий жоден інший аромат регексу, який реалізує розгалуження; Оператор навіть не задокументований у вікіпедії Regular Expression .


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,}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.