Я добавляю второй ответ в ответ на новую информацию, которую вы добавили с момента публикации первого.Моя цель состояла в том, чтобы помочь вам восстановить вашу систему до ее прежнего состояния, когда работали регулярные выражения.Я склонен согласиться с комментатором на той странице, на которую я ссылался, который сказал, что настройки по умолчанию были слишком консервативными.Поэтому я поддерживаю этот ответ, но я не хочу, чтобы кто-либо думал, что он сможет решить все свои проблемы с регулярными выражениями, потратив на них больше памяти.
Теперь, когда я увидел ваши регулярные выражения в реальном мире, я должен сказать, что у вас есть еще одна проблема.Я проверил это третье регулярное выражение на странице, на которую вы ссылались в RegexBuddy, и вот результаты, которые я получил:
(?ims)<tr.*?>.*?<b>.*?first science area of study.*?</b>.*?</tr>.*?<tr.*?>.*?<td.*?>.*?<b>(.*?) \((.*?)\).*?</b>(.*?credits.*?)</td>.*?<td.*?>(.*?<a .*?)</td>.*?</tr>
course name start end steps
Match #1 (Comp. Sci.) 10 275 31271
Match #2 (Bio & Chem) 276 341 6986
Match #3 (Enviro) 342 379 5944
Match #4 (Genetics) 386 416 4463
Match #5 (Chem) 417 455 5074
Match #6 (Math) 495 546 15610
Match #7 (Phys & Astro) 547 593 8617
Match #8 (no match) gave up after 1,000,000 steps
Вы, наверное, слышали, что многие люди говорят, что не жадные регулярные выражения всегда возвращают самое короткое совпадение,так почему же этот вернул первый матч, который на 200 строк длиннее, чем остальные?Возможно, вы слышали, что они более эффективны, потому что они не отступают так сильно, так почему этот шаг занял более 30 000 шагов, чтобы завершить первый матч, и почему он эффективно заблокировал последнюю попытку, когда ни один матч не был возможен?
Во-первых, не существует такого понятия, как жадное или не жадное регулярное выражение.Только отдельные квантификаторы могут быть описаны таким образом.Регулярное выражение, в котором каждый квантификатор является жадным, не обязательно возвращает самое длинное возможное совпадение, а название «не жадное регулярное выражение» еще менее точно.Жадный или не жадный, движок регулярных выражений всегда начинает пытаться сопоставиться при первой же возможности, и он не сдается на стартовой позиции, пока не будут исследованы все возможные пути из него.
Нежадные квантификаторыявляются только удобством;в них нет ничего волшебного.Вы до сих пор, автор регулярных выражений, должны направлять движок регулярных выражений к правильному и эффективному соответствию.Ваше регулярное выражение может возвращать правильные результаты, но затрачивает на это много сил.Он потребляет много символов, которые ему не нужны в начале, он мечется о бесконечном изучении одних и тех же символов снова и снова, и требуется слишком много времени, чтобы понять, когда путь, по которому он идет, не может привести к совпадению.
Теперь проверьте это регулярное выражение:
(?is)<tr[^<]*(?:<(?!/tr>|b>)[^<]*)*<b>\s*first science area of study\s*</b>.*?</tr>.*?<tr.*?>.*?<td.*?>.*?<b>(.*?) \((.*?)\).*?</b>(.*?credits.*?)</td>.*?<td.*?>(.*?<a .*?)</td>.*?</tr>
course name start end steps
Match #1 (Comp. Sci.) 209 275 9891
Match #2 (Bio & Chem) 276 341 5389
Match #3 (Enviro) 342 379 5833
Match #4 (Genetics) 386 416 4222
Match #5 (Chem) 417 455 4961
Match #6 (Math) 495 546 9899
Match #7 (Phys & Astro) 547 593 8506
Match #8 (no match) reported failure in 139 steps
После первого </b>
все будет так, как вы его написали.Эффект моих изменений заключается в том, что он не начинает сопоставляться по-настоящему, пока не найдет элемент <TR>
, который содержит первый интересующий нас тег <B>
:
<tr[^<]*(?:<(?!/tr>|b>)[^<]*)*<b>\s*first science area of study\s*</b>
Эта часть тратит больше всегосвоего времени жадно потребляющие символы с [^<]*
, что значительно быстрее, символ за персонажем, чем не жадный .*?
.Но гораздо важнее то, что практически не требуется времени, чтобы выяснить, когда больше нет совпадений.Если есть золотое правило производительности регулярных выражений, то оно таково: когда попытка матча потерпит неудачу, она должна завершиться как можно быстрее.