Регулярное выражение Python для разделения параметризованного текстового файла - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь разбить файл, который содержит формат 'string = float' несколько раз. Ниже показано, как файл выглядит.

+name1 = 32    name2= 4
+name3 = 2     name4 = 5
+name5 = 2e+23
...  

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

a={name1:32, name2:4, name3:2, name4:5, name5:2e+23}

Я новичок в регулярных выражениях, и мне трудно понять, что делать. После некоторого поиска в Google, я попытался сделать, как показано ниже, чтобы удалить символ "+" и пробелы.

p=re.compile('[^+\s]+')
splitted_list=p.findall(lineof_file)

Но это дало мне две проблемы .. 1. когда нет пробела между именем и знаком "=", он не спилит. 2. для чисел, таких как 2e + 23, он разделяет знак + между ними.

Мне удалось разобрать файл, как я хотел после некоторой модификации кода Депперма.
Но я столкнулся с другой проблемой. Чтобы лучше объяснить мои проблемы. Ниже показано, как может выглядеть мой файл. После знака «+» пара параметров и значений может появиться со знаком «=». Имя параметра может содержать алфавит и цифру в любой позиции. Также значение может содержать знак + - с научным уведомлением (E / e- +). И иногда значение может быть математическим выражением, если оно заключено в одинарные кавычки.

+ abc2dfg3  = -2.3534E-03    dfe4c3= 2.000
+ abcdefg= '1.00232e-1*x' * bdfd=1e-3

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

re.findall("(\w+)\s*=\s*([+-]?[\d+.Ee+-]+|'[^']+')",eachline)

Но теперь моя проблема иногда похожа на "* bdfd = 1e-3", может быть какой-то комментарий. Все, что после * (звездочка) в моем файле, следует рассматривать как комментарий, но не в том случае, если * присутствует внутри строки в одинарных кавычках. С приведенным выше регулярным выражением, он также анализирует "bdfd = 1e-3", но я хочу, чтобы он не анализировался. Я пытался найти решение в течение нескольких часов, но пока не смог найти никакого решения.

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Вы можете объединить регулярное выражение с разбиением строки:

Создать файл:

t =""" 

+name1 = 32    name2= 4
+name3 = 2     name4 = 5
+name5 = 2e+23"""

fn = "t.txt"
with open(fn,"w") as f:
    f.write(t)

Разделить файл:

import re
d = {}
with open(fn,"r") as f:
    for line in f:    # proces each line
        g = re.findall(r'(\w+ ?= ?[^ ]*)',line)    # find all name = something
        for hit in g:                              # something != space
            hit = hit.strip()                      # remove spaces
            if hit:
                key, val = hit.split("=")          # split and strip and convert  
                d[key.rstrip()] = float(val.strip())   # put into dict
print d

Выход:

{'name4': 5.0, 'name5': 2e+23, 'name2': 4.0, 'name3': 2.0, 'name1': 32.0}
0 голосов
/ 26 апреля 2018

Вам не нужно регулярное выражение для достижения вашей цели. Вы можете использовать built-in методы Python.

your_dictionary = {}
# Read the file 
with open('file.txt','r') as fin:
  lines = fin.readlines()
# iterate over each line
for line in lines:
  splittedLine = line.split('=')
  your_dictionary.push({dict.push({
  key:   splittedLine[0],
  value: splittedLine[1]
});
print(your_dictionary)

Надеюсь, это поможет!

0 голосов
/ 26 апреля 2018

Я бы предложил просто взять имя и значение, а не беспокоиться о пробелах или нежелательных символах. Я бы использовал это регулярное выражение: (name\d+)\s?=\s?([\de+]+), которое получит имя, а затем вы также сгруппируете число, даже если у него есть буква e или пробел.

import re
p=re.compile('(name\d+)\s*=\s*([\de+]+)')

a ={}
with open("file.txt", "r") as ins:
    for line in ins:
        splitted_list=p.findall(line)
        #splitted_list looks like: [('name1', '32'), ('name2', '4')]
        for group in splitted_list:
            a[group[0]]=group[1]
print(a)
#{'name1': '32', 'name2': '4', 'name3': '2', 'name4': '5', 'name5': '2e+23'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...