Python: regex lookbehind возвращает слово после одинарных или двойных кавычек

#python #regex #lookbehind

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

Вопрос:

У меня есть файл с содержимым, как показано ниже. Я пытаюсь извлечь слово рядом с «-x» в файле и, наконец, должен получить только результаты uniq. В рамках этого я попробовал приведенное ниже регулярное выражение, но получил только одинарные и двойные кавычки в выходных данных. Когда я использую regex только для двойных кавычек, я получаю результат.

Содержимое файла

 00 04 * * 2-6   testuser   /get_results.sh -q -x 'igp_srm_m' -s 'yesterday' -e 'yesterday' -m '2048' -b >>'/var/log/process/srm-console.log' 2>amp;1
00 10 * * 2-6   testuser   /get_results.sh -q -x 'igp_srm_m' -s 'yesterday' -e 'yesterday' -m '2048' -w '720' >>'/var/log/process/srm-console.log' 2>amp;1

00 08 * * 1-5   testuser   /get_results.sh -q -x "igp_france" -s "today" -e "today" -m "90000" -b -z partA >>"/var/log/process/france-partA-console.log" 2>amp;1
00 12 * * 2-6   testuser   /get_results.sh -q -x "igp_france" -s "yesterday" -e "yesterday" -m "90000" -w "900" -z partA >>"/var/log/process/france-partA-console.log" 2>amp;1

00 08 * * 1-5   testuser   /get_results.sh -q -x "igp_france" -s "today" -e "today" -m "90000" -b -z partB >>"/var/log/process/france-partB-console.log" 2>amp;1
00 12 * * 2-6   testuser   /get_results.sh -q -x "igp_france" -s "yesterday" -e "yesterday" -m "90000" -w "900" -z partB >>"/var/log/process/france-partB-console.log" 2>amp;1

00 12 * * 2-6   testuser   JAVA_OPTS='-server -Xmx512m' /merge.sh "yesterday" "igp_france" "partA,partB" >>"/var/log/process/france-console.log" 2>amp;1
00 08 * * 1-5   testuser   /get_results.sh -q -x "igpswitz_france" -s "today" -e "today" -m "15000" -b >>'/var/log/process/igpswitz_france-console.log' 2>amp;1
00 12 * * 2-6   testuser   /get_results.sh -q -x "igpswitz_france" -s "yesterday" -e "yesterday" -m "15000" -Dapc.maxalerts=8000 -w "900" >>'/var/log/process/igpswitz_france-console.log' 2>amp;1

30 07 * * 2-6   testuser   /get_results.sh -q -x "igp_franced" -s 'yesterday' -e 'yesterday' -m "105000" -b >>"/var/log/process/franced-console.log" 2>amp;1
15 12 * * 2-6   testuser   /get_results.sh -q -x "igp_franced" -s 'yesterday' -e 'yesterday' -m "105000" -w "960" >>"/var/log/process/franced-console.log" 2>amp;1
 

Пробный синтаксис

 import re
with open ("test2") as file:
        for line in file:
                try:
                        m=re.search('(?<=-x ("|'))(w )',line)
                        print m.group(1)
                except:
                        m = None
 

Ожидаемый результат

 igp_srm_m
igp_france
igpswitz_france
igp_franced
 

Полученный результат

 '
'
"
"
"
"
"
"
"
"
 

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

Рабочий скрипт только для двойных кавычек

 import re
with open ("test2") as file:
        for line in file:
                try:
                        m = re.search('(?<=-x ")(w*)', line)
                        print m.group(1)
                except:
                        m = None
 

Полученный результат — поиск только по двойным кавычкам

 igp_france
igp_france
igp_france
igp_france
igpswitz_france
igpswitz_france
igp_franced
igp_franced
 

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

1. Кажется, вам также нужно избегать дубликатов, верно? Если это необходимо, и если вы используете regex вместо модуля re, вы можете избавиться от этих дубликатов, используя maybe (-x ("|'))(w )2(?!.*(?1)3["|']) .

Ответ №1:

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

В вашем шаблоне значения находятся в группе 2, но вы можете немного оптимизировать шаблон. одинарная и двойная кавычки могут использоваться в классе символов (["']) и записываться в группу 1. Затем вы можете использовать обратную ссылку для сопряжения совпадающей цитаты с помощью

 -x (["'])(w )1
 

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

 import re

result = set()

with open ("test2") as file:
    for line in file:
        try:
            m = re.search(r"-x (["'])(w )1", line)
            result.add(m.group(2))
        except:
            m = None

print(result)
 

Вывод

 {'igp_france', 'igp_srm_m', 'igp_franced', 'igpswitz_france'}
 

Ответ №2:

В

 m=re.search('(?<=-x ("|'))(w )',line)
print m.group(1)
 

вместо group(1) используйте group (2),
в основном,

 m=re.search('(?<=-x ("|'))(w )',line)
print m.group(2)
 

От попытки на https://regex101.com /, группа 1 отображается как ' , в то время как использование группы 2 дает требуемый результат.

Двойные кавычки работают правильно, поскольку ваш требуемый вывод уже находится в группе 1.