Я хочу получить тексты, пока он не найдет определенное совпадение.
Например:
Я хочу получить весь текст, прежде чем он найдет слово the
В настоящее время у меня есть это правило /([[:alnum:]|\s|.]*)(?!the)/ui
С этим текстом:
this is completely customizable through the dashboard. This is a separate area from the main c
Проблема в том, что первая группа соответствует всей строке и не останавливается, когда слово the
был найден. Я ожидаю, что это:
Матч 1: this is completely customizable through
Матч 2: dashboard. This is a separate area from
Что я делаю неправильно?
Здесь образец
Вам просто нужно использовать ленивое соответствие с прогнозом:
/.+?(?=\bthe\b)/s
Увидеть regex demo, спички
this is completely customizable through
the dashboard. This is a separate area from
s
модификатор используется, чтобы заставить .
чтобы соответствовать новой строке тоже. Ленивое соответствие означает, что он будет искать ближайший the
а также \b
помогите найти все слово the
не часть слова theater
,
Ленивое соответствие, как описано в rexegg.com:
Ленивый
.*?
гарантирует, что квантифицированная точка соответствует только тому количеству символов, которое необходимо для успешного выполнения оставшейся части шаблона.
Ваш ([[:alnum:]|\s|.]*)
регулярное выражение немного неправильно, так как |
внутри класса символов рассматривается как символ буквального канала. Также, .
включает в себя [:alnum:]
Таким образом, это избыточно. Вы можете написать это как ([\s.]*)
, или просто .*
с /s
модификатор (dotall, singleline). Но так как он жадный (то есть сопоставляет столько символов, сколько может при поиске совпадения), он остановится только до финала the
, Итак, вместо *
вам нужно использовать *?
ленивый соответствия.
Поскольку вас могут не интересовать пустые совпадения, *
(0 или более вхождений) следует заменить на +
(1 или более вхождений предыдущего подшаблона).
Вот PHP демо:
$re = '/.+?(?=\bthe\b)/s';
$str = "this is completely customizable through the dashboard. This is a separate area from the main c";
preg_match_all($re, $str, $matches);
print_r($matches[0]);
Вы должны использовать не жадный модификатор U с большой буквы
Кроме того — попробуйте использовать просто «во» во втором замыкании
/([[:alnum:]|\s|.]*)(the)/Ui
Проверь это
Используйте не жадный с *?
вместо только *
,
Как это:
.*?(?=the)
Сравните это
.*?(?=the)
с этим
.*(?=the)
Так как вы хотите исключить слово the
, лучший способ — разделить строку вместо того, чтобы пытаться сопоставить все до этого слова:
$result = preg_split('~\bthe\b~i', $str);
array_pop($result);
print_r($result);
Вам нужно удалить последний элемент с array_pop
так как это не сопровождается the
,
Как в сторону (?!...)
средства не сопровождается а также (?=...)
средства с последующим.