Регулярное выражение для URL-адреса, переходящего в бесконечный цикл с использованием python

#python-3.x #regex #pandas

Вопрос:

Я использую этот код для определения URL-адреса с помощью python3:

Код:

 regex = r"(?i)b((?:https?://|wwwd{0,3}[.]|[a-z0-9.-] [.][a-z]{2,4}/)(?:[^s()<>] |(([^s()<>] |(([^s()<>] )))*)) (?:(([^s()<>] |(([^s()<>] )))*)|[^s`!()[]{};:'".,<>?«»“”‘’]))"
def replace_urls(text):
#     print("replace_urls",text)
    return re.sub(regex, 'URL_ENTITY', text, flags=re.MULTILINE)
 

В каком-то конкретном предложении регулярное выражение переходит в бесконечный цикл, и код продолжает выполняться.

Это правильное регулярное выражение или что-то нужно изменить?

Пример, где он переходит в бесконечный цикл:

 x="abc.com/us/help/article/does-abc-cover-my-purchase-if-there's-a-problem-(purchase-protection-for-buyers) for further information about our Purchased Protection Program."
 

Почему он переходит в бесконечный цикл?

Комментарии:

1. Может быть, вы могли бы привести пример, для которого это не удается?

2. Если вы обнаружили случай, приводящий к катастрофическому возврату, вы должны исправить регулярное выражение. Что это за струна? Кроме того, удалите flags=re.MULTILINE , в шаблоне нет ^ / $ якорей.

Ответ №1:

Во-первых, без одного и того же текста для тестирования я не могу быть полностью уверен, что это сработает.
Вы можете попробовать это, чтобы посмотреть, излечит ли это проблему.

Есть 2 замеченных проблемы. В одном жадном количественном кластере у вас есть вложенный квантор, такой как (?: A | (?: BsomecluseterA) )
Другая проблема заключается в том, что последний кластер почти идентичен первому,
только с небольшим отличием.

Вы должны быть в состоянии отменить предложение quantified quantified
, просто избавившись от квантора.
Затем соедините два почти одинаковых кластера и вычтите разницу.

В результате получается следующее

 (?i)b((?:https?://|wwwd{0,3}[.]|[a-z0-9.-] [.][a-z]{2,4}/)(?:[^s()<>]|((?:[^s()<>]|(?:([^s()<>] )))*)) [^s`!()[]{};:'".,<>?«»“”‘’]?(?<=[^s`!()[]{};:'".,<>?«»“”‘’]|)))
 

затем с расширением

  (?i)
 b 
 (                                   # (1 start)
    (?:
       https?://
     | www d{0,3} [.] 
     | [a-z0-9.-]  [.] [a-z]{2,4} /
    )
    (?:
       [^s()<>] 
     | 
       ( 
       (?:
          [^s()<>] 
        | (?: ( [^s()<>]  ) )
       )*
       ) 
    ) 
    [^s`!()[]{};:'".,<>?«»“”‘’]? 
    # might be necessary, might not
    (?<= [^s`!()[]{};:'".,<>?«»“”‘’] | ) )
 )                                   # (1 end)
 

Если это не сработает, существуют утверждения и обратные ссылки, которые
можно использовать для моделирования атомарных групп.


10/28/2021 решение, примененное к новому образцу, предоставленному:

 abc.com/us/help/article/does-abc-cover-my-purchase-if-there's-a-problem-(purchase-protection-for-buyers) for further information about our Purchased Protection Program.
 

https://regex101.com/r/KpIhZz/1

Комментарии:

1. Я уже упоминал пример выше.

2. @MAC -Если это поможет, я опробовал решение на вашем новом образце. Кажется, все в порядке, ссылка внизу.