.*?id="number"[^>]*?>([^<]+?).*
Это действительно регулярное выражение, которое вы используете? Я спрашиваю, потому что ([^<]+?)
всегда будет соответствовать ровно одному символу, как если бы вы написали ([^<])
. Квантор +
должен совпадать хотя бы один раз, но из-за нежелания немедленно переходить к следующей части - .*
- которая всегда успешна. Удаление .*
и переключение на find()
или lookingAt()
также не изменит это поведение (хотя, вероятно, будет немного быстрее получить тот же результат). Если вы хотите сопоставить весь текст до следующей угловой скобки, вам следует избавиться от знака вопроса: ([^<]+)
.
[^>]*?>
тоже не имеет особого смысла. Вы должны потреблять столько не скобок, сколько есть, прежде чем вы сможете сопоставить скобки, так какой смысл делать этот квантификатор неохотным? На самом деле, нет смысла делать его жадным; если [^>]*
соответствует как можно большему количеству символов, а следующий символ не равен '>', то вы знаете, что возврат не поможет. Вы также можете использовать квантификатор притяжений - [^>]*+>
- или атомарную группу - (?>[^>]*+)>
- если их поддерживает регулярное выражение.
Первая количественная часть - .*?
- единственная, которая используется правильно (если не оптимально). Помещение в начало регулярного выражения имитирует поведение find()
, когда вы используете lookingAt()
или (с .*
в конце) matches()
. Однако, как вы обнаружили, отключение и использование find()
более эффективно.
Неохотные квантификаторы очень удобны, но в последнее время кажется, что они становятся переэкспонированными. Все чаще и чаще я вижу людей, которые дают советы «Используйте неохотные квантификаторы» без объяснения причин или квалификации - просто еще одна серебряная пуля. И я полагаю, что такие регулярные выражения, как в этом вопросе, являются результатом. Из трех неохотных квантификаторов один должен был быть жадным, один должен был быть собственником, а другой вообще не должен был там быть.
РЕДАКТИРОВАТЬ: Вот пример, чтобы проиллюстрировать некоторые из того, о чем я говорю, и ответить на комментарий Стивена С. Учитывая эту строку:
<div id="number" class="whatever">abc123</div>
... динамические части регулярного выражения совпадают так:
.*? => '<div '
[^>]*? => ' class="whatever"'
([^<]+?) => 'a'
.* => 'bc123</div>'
Изменение всех неохотных квантификаторов на жадные не меняет общее совпадение (всю строку) и не меняет того, что сопоставляется первым двум динамическим частям. Но последние два перераспределяются:
([^<]+) => 'abc123'
.* => '</div>'
Глядя на оригинальное регулярное выражение, я подумал, что это должен быть желаемый результат; зачем использовать такое сложное подвыражение внутри группы захвата, если не захватывать весь контент, 'abc123'
? Вот что заставляет меня верить, что неохотные квантификаторы использовались вслепую как панацея.
Еще одна вещь: оглядываясь назад, я вижу, что ОП на самом деле не говорит , он удалил .*?
из передней части регулярного выражения, когда он переключился на метод find()
, @ Бен, если ты этого не сделал, ты должен; сейчас все просто замедляется. Это оставило бы вас с этим регулярным выражением:
id="number"[^>]*+>([^<]+)
Я тоже не хочу, чтобы кто-то думал, что я оспариваю принятый ответ. Я просто чешу этот зуд, который у меня есть из-за чрезмерного / неправильного использования неохотных квантификаторов.