Возникли проблемы со следующим регулярным выражением python

#python #regex

#python #регулярное выражение

Вопрос:

Привет, у меня есть файл конфигурации следующего типа, который я пытаюсь проанализировать с помощью регулярных выражений в Python. Вы увидите, что строки, начинающиеся с test, встречаются дважды, и я после всего второго экземпляра, который имеет два разных ключевых слова: description и no shutdown .

    test 68068070 same "random-text" someone 68068070 new
       int "random-test" new
       exit
       int "somemore-random-text" new
       exit
    exit
    test 58698496 name "58698496" someone 1 new
       interface "some random text" new
       exit
    exit
    test 4035849058 name "can be any random text" someone 76060600 new
       int "another random text" new
       exit
    exit
    test 806406450 name "random text goes here" someone 89899 new
    exit
    test 68068070 same "random-text" someone 68068070 new
       description "random-text-here"
       Lots of random text goes here
           no shutdown
       exit
       no shutdown
    exit  
    test 806406450 name "random text goes here" someone 89899 new
     description "random-text-here"
       Lots of random text goes here
           no shutdown
       exit
       no shutdown
    exit  
    test 58698496 name "58698496" someone 1 new
     description "random-text-here"
         Lots of random text goes here
           no shutdown
       exit
       no shutdown
    exit  
    test 58698496 name "58698496" someone 1 new
    description "random-text-here"
       Lots of random text goes here
           no shutdown
       exit
       no shutdown
    exit  
    test 4035849058 name "can be any random text" someone 76060600 new
    description "random-text-here"
       Lots of random text goes here
           no shutdown
       exit
       no shutdown
    exit 
  

Из приведенного выше текста я хочу захватить только следующие экземпляры:

 test 68068070 same "random-text" someone 68068070 new
   description "random-text-here"
   Lots of random text goes here
       no shutdown
   exit
   no shutdown
exit  
test 806406450 name "random text goes here" someone 89899 new
 description "random-text-here"
   Lots of random text goes here
       no shutdown
   exit
   no shutdown
exit  
test 58698496 name "58698496" someone 1 new
 description "random-text-here"
   Lots of random text goes here
       no shutdown
   exit
   no shutdown
exit  
test 58698496 name "58698496" someone 1 new
description "random-text-here"
   Lots of random text goes here
       no shutdown
   exit
   no shutdown
exit  
test 4035849058 name "can be any random text" someone 76060600 new
description "random-text-here"
   Lots of random text goes here
       no shutdown
   exit
   no shutdown
exit 
  

Регулярное выражение, которое я пробовал в regex101, выглядит следующим образом:

 testsd{1,10}s. ?news description.*?nosshutdowns*exit
  

С включенными флагами gs.

регулярное выражение 101ссылка

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

    test 68068070 same "random-text" someone 68068070 new
       int "random-test" new
       exit
       int "somemore-random-text" new
       exit
    exit
    test 58698496 name "58698496" someone 1 new
       interface "some random text" new
       exit
    exit
    test 4035849058 name "can be any random text" someone 76060600 new
       int "another random text" new
       exit
    exit
    test 806406450 name "random text goes here" someone 89899 new
    exit
  

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

    test 68068070 same "random-text" someone 68068070 new
       description "random-text-here"
       Lots of random text goes here
           no shutdown
       exit
       no shutdown
    exit  
  

Любая помощь о том, как я могу настроить или изменить свое регулярное выражение, чтобы исправить это.
Я пытался использовать отрицательный прогноз, т. Е. Не совпадать с int или даже с положительным прогнозом для поиска описания, но я не добился успеха ни с одним из них.
Спасибо

Еще одна проблема, с которой я столкнулся, заключается в следующем:

Бывают случаи, когда отключение не происходит много раз в одном экземпляре, например:

    test 68068070 same "random-text" someone 68068070 new
       description "random-text-here"
       Lots of random text goes here
           no shutdown
       exit
    exit  
        Lots of random text goes here
        no shutdown
       exit
    exit  
        Lots of random text goes here
           no shutdown
       exit
    exit  
     Lots of random text goes here
           no shutdown
        exit
      exit
        no shutdown
    exit
exit
  

Как мне выбрать этот сценарий до конца, чтобы не завершать работу.На этом регулярное выражение приходит и останавливается при первом no shutdown.
Итак, это регулярное выражение работает:

 testsd{1,10}s[^n] news description. ?nosshutdowns exit
  

Но останавливается при первом no shutdown. Есть идеи, как я дойду до последнего без выключения.

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

1. регулярное выражение не является хорошим выбором для анализа отформатированных многострочных вложенных форматов данных.

2. Привет, есть идеи, что еще я могу использовать для извлечения требуемого текста. К сожалению, это специфичный для поставщика текстовый вывод с устройства, которое не является JSON или XML.

Ответ №1:

Вы можете использовать это регулярное выражение с отрицаемым символьным классом:

 testsd{1,10}s[^n] news description. ?nosshutdowns exit
#               ^^^^^^  [^n] matches anything but line break 
  

Убедитесь, что вы используете DOTALL или s mode для своего регулярного выражения.

Демонстрация регулярных выражений

В вашем регулярном .* выражении соответствует любому символу, включая разрывы строк, поскольку вы используете s mode, следовательно, он слишком сильно совпадает по блокам. [^n] с другой стороны, совпадения только в пределах одной строки.

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

1. Привет, Анубхава, спасибо, ваше предложение устранило мою проблему, хотя я не понимаю, как работает [^ n] . Но я отредактировал свой пост, и вы увидите, что я столкнулся с другой проблемой, когда в блоке много инструкций no shutdown, и я хочу захватить их все. Смотрите Обновленный пост, есть идеи, как я могу зафиксировать этот сценарий, пожалуйста.

2. Я уже объяснил в ответе, что [^n] соответствует чему угодно, кроме разрыва строки.

3. Привет, Анубхава, просто проверяю свое понимание, чтобы убедиться, что я понимаю регулярное выражение и как оно работает, извините, я новичок в регулярных выражениях и пытаюсь понять, как это работает. Мое понимание того, что вы предложили, заключается в следующем: этот бит содержит собственный vprn s[^n] , он соответствует литералу vprn, затем символу пробела, затем мы говорим, что не соответствует символу новой строки, и, используя квантификатор , продолжайте сопоставлять до конца строки.первая строка. Итак, когда вы говорите, что [^n] совпадает только в пределах одной строки, я не понимаю, как это переходит к следующей строке, т.е. s description . ? и т.д.

4. Да, ваше понимание правильное. s description. ? совпадения по строкам из-за использования s DOTALL режима или, который заставляет . (точка) соответствовать любому символу, включая новые строки.

5. tests d{1,10}s[^n] s описание, как s позволяет перейти к следующей строке? s соответствует любому символу пробела, а указывает один или несколько. Имеет ли s особое значение при использовании с флагом re.DOTALL? Я могу понять это описание. ?, это . совпадения между символами новой строки, но до этого мы использовали только s и no . оператор.