Вы должны придерживаться принципа: все последующие смежные подшаблоны не могут совпадать в одном и том же месте строки.Если вы определяете их с помощью *
или ?
, убедитесь, что эти обязательные шаблоны перед ними не соответствуют одному и тому же тексту.Иначе, обновите образец.Или используйте атомные группировки .
Часть (?:https?://|www\d{0,3}[.]|[a-z0-9.-]+[.][a-z]{2,4}/)
является чередованием, где оба могут совпадать в одном и том же месте строки.Этого нельзя избежать, поэтому используйте атомарную группу, чтобы предотвратить возврат в шаблон.
Посмотрите на [a-z0-9.-]+[.]
, .
присутствует в классе +
количественных символов.Сделайте его более линейным, замените его на [a-z0-9-]*(?:\.[a-z0-9-]*)*\.
.
. (?:[^'"\n\r()<>]+|\(([^'"\n\r()<>]+|(\([^'"\n\r()<>]+\)))*\))+
часть является ошибочным шаблоном: [^'"\n\r()<>]+
равен +
количественно, и снова, и это приводит к ситуациям, когда механизм регулярных выражений уменьшает егодо (?:a+)+
, классический сценарий CA.Используйте атомарные группировки, если вы не хотите повторно выбирать, хотя это, кажется, является частью шаблона, соответствующего сбалансированным скобкам, и может быть переписано как [^'"\n\r()<>]*(?:\((?>[^()]+|(?<o>\()|(?<-o>\)))*(?(o)(?!))\)[^'"\n\r()<>]*)*
.
Часть ([^'"\n\r()<>]+|(\([^'"\n\r()<>]+\)))*
похожав приведенной выше части измените (
на (?>
, где вы определите количество группы и единый обязательный шаблон внутри нее.
Фиксированный шаблон -
var pattern = @"(?i)\b((?>https?://|www\d{0,3}\.|[a-z0-9-]*(?:\.[a-z0-9-]*)*\.[a-z]{2,4}/)(?>[^'""\n\r()<>]+|\((?>[^'""\n\r()<>]+|\([^'""\n\r()<>]+\))*\))+(?:\((?>[^'""\n\r()<>]+|(\([^'""\n\r()<>]+\)))*\)|[^]['""\n\r`!(){};:.,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]))";
См. какэто изящно терпит неудачу здесь .