Regex: відповідність до першого виникнення символу


356

Я шукаю шаблон, який відповідає всьому поки першого появи конкретного персонажа, скажімо, ";" - крапка з комою .

Я написав це:

/^(.*);/

Але він насправді відповідає всім (включаючи крапку з комою) до останнього появи крапки з комою.


65
/^(.*?);/також повинен працювати (це називається не жадібним ), але наведені відповіді [^;]*краще використовувати.
Паскаль

як би ви вибрали все після крапки з комою, а не саму крапку з комою.
Мухаммед Умер

бачите, це працює, \w+(?!([^]+;)|;)але це не так? .+(?!([^]+;)|;)
Мухаммед Умер

1
Паскаль, ти повинен був написати це як відповідь!
Шон Кендл

@Pascal Це підходить як відповідь! Дякую!
neverMind9

Відповіді:


503

Тобі потрібно

/[^;]*/

[^;]Є класовий характер , вона відповідає всім , крім крапки з комою.

Щоб цитувати сторінку сторінки perlre:

Ви можете вказати клас символів, додавши до списку символів [], який буде відповідати будь-якому символу зі списку. Якщо перший символ після "[" є "^", клас відповідає будь-якому символу, який не є у списку.

Це повинно працювати в більшості діалектних регексів.


Велика частина цього рішення полягає в тому, що також збігається кінець рядка, наприклад, у моєму випадку я мав, foo=bar;baz=bax;bab=bafі він збігався, bab=bafнавіть немає саме ;того, що мені потрібно. Не впевнений, чому це працює, хоча якщо специфікація каже, що відповідає всім, окрім цільового символу ...
skryvets

303

Би;

/^(.*?);/

робота?

Це ?ледачий оператор, тому регулярний вираз захоплює якомога менше, перш ніж відповідати ;.


4
Так, але після розширення бікарбонату до Тіма Тоді, я вважаю, що заперечені класи символів виграють, оскільки лінивий кількісний показник включає зворотний трекінг. +1 у будь-якому випадку
Amarghosh

3
Варто прочитати тему виступу: blog.stevenlevithan.com/archives/greedy-lazy-performance
Гленн Славен

38

/^[^;]*/

[^;] Говорить, що відповідає нічого, крім крапки з комою. Квадратні дужки - це оператор відповідності набору, він, по суті, відповідає будь-якому символу в цьому наборі символів, ^на початку він робить зворотну відповідність, тому відповідайте будь-якому, що не є в цьому наборі.


3
Майте на увазі, що перший ^ у цій відповіді надає регулярному вираженню зовсім інше значення: Це робить регулярний вираз виглядає лише для збігів, починаючи з початку рядка. У цьому випадку це фактично буде необов’язковим, якщо регулярний вираз запускається лише один раз. Якщо ви хочете шукати декілька збігів у межах одного рядка, перший ^ повинен був би пройти.
Дан Бреслау

4
Він сказав, що хотів зіставити все до першого появи крапки з комою, тому я припустив, що він мав на увазі від початку рядка.
Гленн Славен



8

зразок тексту:

"this is a test sentence; to prove this regex; that is g;iven below"

Якщо, наприклад, у нас є приклад тексту вище, регекс /(.*?\;)/дасть вам усе до першого появи крапки з комою ( ;), включаючи крапку з комою:"this is a test sentence;"


3
не варто уникати ;чародії, оскільки це не регулярний вираз спеціального характеру. Групування ()також не потрібно. Ви можете піти з/.*?;/
Аліаксей Ключнікау

1
так, ви абсолютно праві. втеча більше нагадувала "краще безпечно, ніж шкода"
понцій

2
Це відповідь, яку я шукав. Так що? змушує матч закінчитися при першій появі? Як називається ця ... (назвемо її) властивість регулярного вираження?
Парцифал

1
@Parziphal ?персонаж робить матч лінивим (відповідає якомога менше разів). Придумайте відповідність символів до регулярних крапок до першої крапки з комою, тоді вона не піде далі, тому що здається (ледачий;))
derekantrican

5

це не рішення для регулярного вираження, але щось досить просте для опису вашої проблеми. Просто розділіть рядок і отримайте перший елемент із масиву.

$str = "match everything until first ; blah ; blah end ";
$s = explode(";",$str,2);
print $s[0];

вихід

$ php test.php
match everything until first

5

Це було дуже корисно для мене, оскільки я намагався зрозуміти, як зіставити всі символи в тезі xml, включаючи атрибути. Я зіткнувся з проблемою "відповідає всім до кінця" з:

/<simpleChoice.*>/

але вдалося вирішити проблему за допомогою:

/<simpleChoice[^>]*>/

після прочитання цієї публікації. Дякую всім.


1
Я виявив, що набагато ефективніше насправді розбирати (для кожної мови або фреймворку є свої класи для цього) html / xml через його машинний формат, регулярні вирази призначені для природної мови.
Леон Федотов

1
Приємно. Я використовував це для виправлення XML-документів із синтаксичними помилками в <!DOCTYPE>тегу. Оскільки аналізатор не впорався з цим.
Мартін Шнайдер

5

Це відповідатиме першому виникненню лише у кожному рядку та ігноруватиме наступні події.

/^([^;]*);*/

3

"/^([^\/]*)\/$/" працював на мене, щоб отримати лише найпопулярніші "папки" з масиву, як-от:

a/   <- this
a/b/
c/   <- this
c/d/
/d/e/
f/   <- this

2

Дійсно сумно, що ніхто не дав тобі правильної відповіді ....

В регекс,? робить його не жадібним. За замовчуванням регулярний вираз підходить якнайбільше (жадібний)

Просто додати? і воно буде не жадібним і якнайменше відповідатиме!

Удачі, сподівання, що допомагає.


3
Це в значній мірі залежить від реальної реалізації регулярних виразів, і не кожна реалізація має неактивний режим.
karatedog

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