Regex, чтобы соответствовать только многострочной строке с ключевым словом на своем месте - PullRequest
0 голосов
/ 09 мая 2018

У меня есть файл виртуальных инструментов с блоками, которые могут содержать любую комбинацию атрибутов, выглядящих так:

POINT=69
    Name="M_Frequency Min" Type=ANALOG
    Units="Hz"
    Archive="AVERAGE" Priority=9999 Latch=0
    HysEnable=0 HysVal=0.00000
    Bit="0"
    Category="Meter"
    IsCustom=1
    Interval=0
    Accumulated=0
    DisplayOrder=1
ENDPOINT
POINT=70
    Name="M_Voltage Phase A-N Max" Type=ANALOG
    Units="Volts"
    Archive="AVERAGE" Priority=9999 Latch=0
    HysEnable=0 HysVal=0.000000
    CritHiEnable=0 CritHiLimit=0.000000
    CritLoEnable=0 CritLoLimit=0.000000
    CautHiEnable=0 CautHiLimit=0.000000
    CautLoEnable=0 CautLoLimit=0.000000
    Desc="Voltage Phase A-N Max"
    RW=READ
    Register="9000"
    RegType="H"
    DataType="F"
    Accumulated=0
    DisplayOrder=1
ENDPOINT

Скажем, я бы хотел сопоставить только второй блок (а не первый), используя что-то вроде POINT=[0-9]*(?s)(.*?)(?!ENDPOINT)(\sMax)(.*?)ENDPOINT

Здесь я думаю, что если я установлю свою точку-звездочку так же, чтобы она соответствовала разрывам строк, но затем скажу, чтобы она соответствовала только ленивым, то она остановится, если будет смотреть вперед и увидит что-то, что дисквалифицирует матч. Очевидно, я чего-то здесь не получаю.

Это, конечно, не работает и вместо этого находит весь текст для соответствия. Я также пытался использовать отрицательный набор символов, но также не играл в кости. То, что я пытаюсь сопоставить, это блок POINT to ENDPOINT, только если в нем есть желаемая строка «Max», и я хотел бы дисквалифицировать блок, заканчивающийся на «ENDPOINT», прежде чем нашел «Max».

РЕДАКТИРОВАТЬ1: Вы можете предположить, что будет больше блоков, как этот до и после показанного фрагмента. Я специально пытаюсь получить блок, в котором есть моя целевая строка (поэтому я могу заменить ее другой или удалить). Другие блоки могут содержать или не содержать целевую строку, но если они есть, я бы хотел сопоставлять каждый блок отдельно, а не как одно совпадение.

1 Ответ

0 голосов
/ 09 мая 2018

Отметьте следующее регулярное выражение :

^\s*POINT=\d+\s*$  # A line matching to the word POINT,
                   # followed by the character '=' and one
                   # or more decimal digits surrounded by
                   # whitespace characters.
(?:\r?\n)+   # A zero or one character '\r' before the
             # character '\n'. This sequence may be
             # repeated one or more times.
  (?:                     # Zero or more lines that is not
    ^(?!                  # matched with the ENDPOINT word
      \s*(?:POINT=\d+|    # or the word POINT followed by
            ENDPOINT)\s*$ # the character '=' and zero or
    ).*$                  # more decimal digits surrounded
    (?:\r?\n)+            # by whitespace characters.
  )*
                  # A line that starts with one or more
                  # characters that are not equal to the
  ^[^=]+=.*Max.*$ # '=' character, followed by the '='
                  # character, and finally the word Max
                  # followed by zero or more characters.
  (?:\r?\n)+
  (?:
    ^(?!
      \s*(?:POINT=\d+|ENDPOINT)\s*$
    ).*$
    (?:\r?\n)+
  )*
^\s*ENDPOINT\s*$ # A line matching to the word ENDPOINT,
                 # surrounded by whitespace characters.
...