отрицание группы регулярных выражений - PullRequest
0 голосов
/ 07 января 2019

Я записал файл в большую строку. Я хочу проанализировать строку и создать список диктов на основе jobno. Каждое задание будет иметь переменное количество пар ключ / значение в произвольном порядке. Единственное, на что я могу рассчитывать, это jobno: пара xxxx всегда обозначает начало новой работы

python 2.7
import re
bigstr = "jobno: 4859305 jobtype: ASSEMBLY name: BLUEBALLOON color: red jobno: 3995433 name: SNEAKYPETE jobtype: PKG texture: crunchy"

regexJobA = re.compile(r'((\w+):\s(\w+)\s?)', re.DOTALL)
for mo in regexJobA.finditer( bigstr):
  keyy, valu = mo.groups():
  print keyy + ":" + valu

выходы

jobno:4859305
jobtype:ASSEMBLY
name:BLUEBALLOON
color:red
jobno:3995433
jobtype:PKG
texture:crunchy

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

regexJobB = re.compile(r'((jobno):\s(\w+)\s?)((*not_jobno*):\s(\w+)\s?)+', re.DOTALL)

сделает трюк. Но как отрицать (jobno) группу? Или используйте некоторый ум умных взглядов / взглядов назад / умов, чтобы получить

jobno:4859305 jobtype:ASSEMBLY name:BLUEBALLOON color:red
jobno:3995433 jobtype:PKG texture:crunchy

ТИА,

code_warrior

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Вы можете использовать

regexJobB = re.compile(r'jobno:\s*(\d+)\s*(.*?)(?=\s+jobno:|$)', re.DOTALL)

См. Демоверсию regex . Это позволит вам получить отдельные jobno s, записать их идентификаторы в группу 1, а остальные параметры - в группу 2. Затем вы можете использовать второе регулярное выражение для получения этих параметров или просто использовать разбиение.

См. Демоверсию Python :

import re
bigstr = "jobno: 4859305 jobtype: ASSEMBLY name: BLUEBALLOON color: red jobno: 3995433 name: SNEAKYPETE jobtype: PKG texture: crunchy"

regexJobB = re.compile(r'jobno:\s*(\d+)\s*(.*?)(?=\s+jobno:|$)', re.DOTALL)
for job in regexJobB.finditer(bigstr):
  jobno = job.group(1)
  jobparams = dict(re.findall(r'(\w+):\s*(\w+)', job.group(2)))
  print("No.: {}\nOther params: {}".format(jobno, jobparams))

Выход:

No.: 4859305
Other params: {'color': 'red', 'name': 'BLUEBALLOON', 'jobtype': 'ASSEMBLY'}
No.: 3995433
Other params: {'texture': 'crunchy', 'name': 'SNEAKYPETE', 'jobtype': 'PKG'}

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

  • jobno: - буквенная строка
  • \s* - 0+ пробелов
  • (\d+) - Группа 1: одна или несколько цифр
  • \s* - 0+ пробелов
  • (.*?) - Группа 2: любые 0 или более символов как можно меньше
  • (?=\s+jobno:|$) - до первых 1+ пробелов, за которыми следует jobno: или конец строки.
0 голосов
/ 07 января 2019

Использование re.findall здесь выглядит как улучшение по сравнению с тем, что у вас сейчас есть:

bigstr = "jobno: 4859305 jobtype: ASSEMBLY name: BLUEBALLOON color: red jobno: 3995433 name: SNEAKYPETE jobtype: PKG texture: crunchy"
result = re.findall('\S+\s*:\s*\S+', bigstr)
print(result)

['jobno: 4859305', 'jobtype: ASSEMBLY', 'name: BLUEBALLOON', 'color: red', 'jobno: 3995433',
    'name: SNEAKYPETE', 'jobtype: PKG', 'texture: crunchy']

По крайней мере, это позволяет избежать итерации. Мой ответ предполагает, что у вас есть строка ввода в одну строку. Если вам нужно будет сопоставить несколько строк, мой ответ изменится незначительно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...