Регулярное выражение: соответствие до первого вхождения символа

358

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

Я написал это:

/^(.*);/

Но это на самом деле соответствует всему (включая точку с запятой) до последнего появления точки с запятой.

Леон Федотов
источник
65
/^(.*?);/также должен работать (это называется не жадным ), но [^;]*лучше использовать данные ответы .
Паскаль
как бы вы выбрали все, после точки с запятой, а не точку с запятой.
Мухаммед Умер
видите, это работает, \w+(?!([^]+;)|;)но это не почему? .+(?!([^]+;)|;)
Мухаммед Умер
1
Паскаль, ты должен был написать это как ответ!
Шон Кендл
@Pascal Это подходит как ответ! Спасибо!
neverMind9

Ответы:

503

Тебе нужно

/[^;]*/

[^;]Является классовым характером , она соответствует всем , кроме точки с запятой.

Чтобы цитировать perlreсправочную страницу:

Вы можете указать класс символов, заключив в [] список символов, который будет соответствовать любому символу из списка. Если первым символом после «[» является «^», класс соответствует любому символу, отсутствующему в списке.

Это должно работать на большинстве диалектов регулярных выражений.

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

Было бы;

/^(.*?);/

Работа?

Оператор ?lazy, поэтому регулярное выражение захватывает как можно меньше, прежде чем сопоставлять ;.

RJFalconer
источник
4
да, но после бикарбонатного расширения Тима Тоади, я считаю, что отрицательные классы персонажей выигрывают, так как ленивый квантификатор включает обратный ход. +1 в любом случае.
Амаргош
3
Стоит почитать на тему производительности: blog.stevenlevithan.com/archives/greedy-lazy-performance
Гленн Славен
38

/^[^;]*/

[^;] Говорит, что соответствует чему угодно, кроме точки с запятой. Квадратные скобки - это оператор сопоставления наборов, по сути, он соответствует любому символу в этом наборе символов, а ^в начале делает его обратным, поэтому сопоставляйте все, что не входит в этот набор.

Гленн Славен
источник
3
Имейте в виду, что первый ^ в этом ответе дает регулярному выражению совершенно другое значение: оно заставляет регулярное выражение искать только совпадения, начинающиеся с начала строки. В этом случае это было бы эффективно, если вы запускаете регулярное выражение только один раз. Если вы хотите найти несколько совпадений в одной строке, первый ^ должен идти.
Дэн Бреслау
4
Он сказал, что хочет сопоставить все до первого появления точки с запятой, поэтому я предположил, что он имел в виду с самого начала строки.
Гленн Славен
15

Пытаться /[^;]*/

Google regex character classesдля деталей.

Дэн Бреслау
источник
8

Образец текста:

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

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

poncius
источник
3
не требуется экранировать ;символ, потому что это не регулярное выражение. Группировка также ()не требуется. Вы можете пойти с/.*?;/
Алексей Ключников
1
да, вы совершенно правы побег был больше похож на «лучше в безопасности, чем
потом
2
Это ответ, который я искал. Так что ? завершает матч в первом случае? Как называется это ... (назовем это) свойство регулярного выражения?
Parziphal
1
@Parziphal ?персонаж делает матч ленивым (сопоставляя как можно меньше раз). Подумайте о регулярных выражениях, совпадающих с символами вплоть до первой точки с запятой, тогда они не идут дальше, потому что они
сдаются
5

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

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

вывод

$ php test.php
match everything until first
ghostdog74
источник
5

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

/<simpleChoice.*>/

но смог решить проблему с:

/<simpleChoice[^>]*>/

после прочтения этого поста. Спасибо всем.

Yardboy
источник
1
Я обнаружил, что на самом деле более эффективно анализировать (каждый язык или фреймворк имеют свои собственные классы для этого) html / xml из-за его машинного формата, регулярные выражения для естественного языка.
Леон Федотов
1
Ницца. Я использовал это, чтобы исправить документы XML с синтаксическими ошибками в <!DOCTYPE>теге. Так как парсер не смог с этим справиться.
Мартин Шнайдер
5

Это будет соответствовать до первого вхождения только в каждой строке и будет игнорировать последующие вхождения.

/^([^;]*);*/
mchid
источник
3

"/^([^\/]*)\/$/" работал для меня, чтобы получить только верхние «папки» из массива, как:

a/   <- this
a/b/
c/   <- this
c/d/
/d/e/
f/   <- this
sPooKee
источник
2

Действительно печально, что никто не дал вам правильный ответ ....

В регулярных выражениях? делает это не жадным. По умолчанию регулярное выражение будет соответствовать столько, сколько может (жадный)

Просто добавить? и это будет не жадным и соответствовать как можно меньше!

Удачи, надеюсь, это поможет.

L1amm
источник
3
Это сильно зависит от фактической реализации регулярных выражений, и не каждая реализация имеет не жадный режим.
каратэдог
0

я нашел это

/^[^,]*,/

работает хорошо.

',' будучи здесь "разделителем".

BookerVII
источник