2014-11-21 13 views
0

Я пытаюсь заменить данный шаблон регулярными выражениями на Python, используя re. Вот кусок кода Python Я написал:Python regex: заменить игнорирование пустой строки

import re 

fname = './prec.f90' 
f = open(fname) 
lines = f.readlines() 
f.close() 
for i, line in enumerate(lines): 
    search = re.findall('([\d*]?\.[\d*]?)+?[^dq\_]', line) 
    if search != []: 
     print('Real found in line #%d: ' %i) 
     print search 
     print('The following line:\n %s' %line) 
     print('will be replace by:') 
     newline = re.sub('([\d*]?\.[\d*]?)+?[^dq\_]', r'\g<1>d0\g<2>', line) 
     print('%s' %newline) 

И prec.f90 содержит что-то подобное (это просто пример, это не означает, что все строки, которые я хочу, чтобы заменить иметь вид [x]_[yz] = ...;):

x_pr = 0.1; y_pr = 0.2; z_pr = 0.1q0 
    x_sp = 0.1; y_sp = 0.1d0; z_sp = 0.1q0 
    x_dp = 0.1; y_dp = 0.1d0; z_dp = 0.1q0 
    x_qp = .1; y_qp = 0.1d0; z_qp = 0.1q0 
    x_db = 0.; y_db = 0.1d0; y_db = 0.1q0 

Моя цель состоит в том, чтобы изменить всю картину, как 0.1, .1 и 0., чтобы получить что-то вроде 0.1d0; Я не хочу изменять другие шаблоны. Проблема в том, что re.findall('[\d*]?\.[\d*]?)+?([^dq\_]') соответствует шаблону, который я ищу, но также возвращает пустую строку для других. Поэтому, когда я запускаю этот фрагмент кода, он терпит неудачу, не имея возможности заменить совпадение первой и второй групп в re.sub() для пустых строк.

Я думаю, что одним из решений было бы игнорировать пустую строку в re.sub или иметь что-то вроде условного аргумента в ней, но я не мог понять, как это сделать.

Любая помощь будет оценена!

+0

Он не выполняет [подпункт пустой строки], потому что вы сделали все компоненты необязательными с '*'. Какова минимальная строка, которая будет на строке, которую вы хотите заменить? Если это '.x', то измените вторую' \ d * 'на' \ d + ' – beroe

+0

. Проблема в том, что они могут иметь 3 формы, которые я упомянул:' x.y', '.y' и' x.'. Я хочу (и нужно) охватить все эти случаи. – MBR

ответ

0

Я наконец придумал этот кусок кода, который работает по назначению:

import re 

fname = './prec.f90' 
f = open(fname) 
lines = f.readlines() 
f.close() 
# If there was no end of the line character (\n) we would need to check if 
# this is the end of the line (something like ([^dq\_0-9]|$) 
regex = re.compile(r'(\d*\.\d*)([^dq\_0-9])') 
for i, line in enumerate(lines): 
    search = regex.findall(line) 
    if search != []: 
     print('Real found in line #%d: ' %i) 
     print search 
     print('The following line:\n %s' %line) 
     print('will be replace by:') 
     newline = regex.sub(r'\g<1>d0\g<2>', line) 
     print('%s' %newline) 

я первый придумал более сложное регулярное выражение ([\d*]?\.[\d*]?)+?[^dq\_], потому что иначе я всегда соответствовать первая часть любой строки, заканчивающаяся d, q или _. Это было связано с тем, что \d* не был достаточно жадным; для добавления 0-9 в набор «ignore» решается проблема.

0

Вы можете упростить sub, как

>>> str="x_db = 0.; y_db = 0.1d0; y_db = 0.1q" 
>>> re.sub(r'(0\.1|\.1|0\.)(?=;)', r'\g<1>0d0', str) 
'x_db = 0.0d0; y_db = 0.1d0; y_db = 0.1q' 

Регулярное выражение (0\.1|\.1|0\.)(?=;) будет соответствовать 0.1, .1 и 0. следуют как ;

+0

Прочтите мое редактирование, строки, которые я хочу заменить, имеют более общую форму, это был всего лишь пример. – MBR

0
(x_[a-zA-Z]{2}\s*=)\s+[^;]+ 

Try this.Replace по \1 0.1d0 .Увидь демо.

http://regex101.com/r/qZ6sE3/2

import re 
p = re.compile(ur'(x_[a-zA-Z]{2}\s*=)\s+[^;]+') 
test_str = u"x_pr = 0.1; y_pr = 0.2; z_pr = 0.1q0\nx_sp = 0.1; y_sp = 0.1d0; z_sp = 0.1q0\nx_dp = 0.1; y_dp = 0.1d0; z_dp = 0.1q0\nx_qp = .1; y_qp = 0.1d0; z_qp = 0.1q0\nx_db = 0.; y_db = 0.1d0; y_db = 0.1q0" 
subst = u"\1 0.1d0" 

result = re.sub(p, subst, test_str) 
+0

Строка, которую я хочу заменить, может иметь гораздо общую форму, чем 'x_ [a-Z] = ...'. Тест в моем вопросе таков: простой тест :) – MBR

+0

@MBR http://regex101.com/r/yP3iB0/6 ??????/ – vks

+0

нет, потому что я не хочу изменять только «0,1», но реально любое реальное число, и у меня нет всех моих выражений, заканчивающихся полуколоновым. и я хочу заменить исходную строку на ее значение, а не на фиктивный '0,1'. – MBR

Смежные вопросы