Уведомления

Группа в Telegram: @pythonsu

#1 Май 5, 2016 15:47:10

exaetr
Зарегистрирован: 2016-05-05
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

Приветствую! Есть некий текстовый файл - test.xml

<?xml version=“1.0” encoding=“UTF-8”?>
<Document>
<NUMBER>00000025</NUMBER>
<Date>2016-02-04</Date>
</Document>

Нужно, чтобы скриптом число в тегах <NUMBER> увеличивалось на единицу.
Как это сделать?

Офлайн

#2 Май 5, 2016 16:18:09

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

use lxml



Офлайн

#3 Май 5, 2016 16:39:39

exaetr
Зарегистрирован: 2016-05-05
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

FishHook, спасибо. Буду изучать)

Офлайн

#4 Май 5, 2016 20:52:05

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

:) do not use lxml
В 90% случаев regexp решает задачу проще и быстрее.
изучайте модуль re. Еще потребуется (если конечно вы не считаете увеличением на единицу увеличение строки на единицу “011”->“0111”)

>>> int("0000222")
222
>>> "{0:07d}".format(222)
'0000222'
import re
s="""<?xml version="1.0" encoding="UTF-8"?>
<Document>
<NUMBER>00000025</NUMBER>
<Date>2016-02-04</Date>
</Document>"""
>>> print(re.sub(r"<NUMBER>(\d+)</NUMBER>",lambda x:"<NUMBER>{:08d}</NUMBER>".format(int(x.group(1))+1),s,count=1))
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<NUMBER>00000026</NUMBER>
<Date>2016-02-04</Date>
</Document>

p.s.
:) согласен - уродство. Но помоему с xml всегда получается уродство.



Отредактировано doza_and (Май 5, 2016 21:10:13)

Офлайн

#5 Май 6, 2016 05:47:56

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

doza_and
regexp решает задачу проще и быстрее.
Ну да, если вот это извращение быстрее и проще чем вот такой код
root = etree.fromstring(s)
node = root.find("NUMBER")
node.text = str(int(node.text) + 1)
то я снимаю шляпу



Офлайн

#6 Май 6, 2016 05:57:34

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

>>> import re
>>> 
>>> s = """
... <?xml version="1.0" encoding="UTF-8"?>
... <Document>
... <NUMBER>00000025</NUMBER>
... <Date>2016-02-04</Date>
... </Document>
... """
>>> 
>>> def tr(s):
...     return '{0:0{1}}'.format(int(s) + 1, len(s))
... 
>>> out = re.sub(r'(?<=<NUMBER>)\d+', lambda mo: tr(mo.group()), s)
>>> print(out)
 
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<NUMBER>00000026</NUMBER>
<Date>2016-02-04</Date>
</Document>
 
>>>

FishHook
то я снимаю шляпу
Через lxml не заменишь так, чтобы не затрагивать остальные теги. Остальные теги потом будут транслироваться с изменением регистра. Document может превратиться в document, а NUMBER - в number. Для программ это неважно, а для человека может быть важно.



Отредактировано py.user.next (Май 6, 2016 06:06:56)

Офлайн

#7 Май 6, 2016 06:53:20

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

py.user.next
Для программ это неважно, а для человека может быть важно.
А для стандарта? xml - регистронезависимый язык, зачем использовать его как регистрозависимый?
И ну и, кстати, вот результат работы моего кода, ничего с изменением регистра не транслируется
<Document>
<NUMBER>26</NUMBER>
<Date>2016-02-04</Date>
</Document>



Офлайн

#8 Май 6, 2016 08:10:33

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

FishHook
А для стандарта? xml - регистронезависимый язык

>>> import lxml.etree
>>> 
>>> doc = lxml.etree.parse('f.xml')
>>> root = doc.getroot()
>>> 
>>> root.find('number')
>>> root.find('NUMBER')
<Element NUMBER at 0xb6fd770c>
>>> 
>>> root.xpath(r'.//number')
[]
>>> root.xpath(r'.//NUMBER')
[<Element NUMBER at 0xb6fd766c>]
>>>

>>> from xml.etree import ElementTree as ET
>>> 
>>> doc = ET.parse('f.xml')
>>> root = doc.getroot()
>>> 
>>> root.find('number')
>>> root.find('NUMBER')
<Element 'NUMBER' at 0xb73dacac>
>>> 
>>> root.findall(r'.//number')
[]
>>> root.findall(r'.//NUMBER')
[<Element 'NUMBER' at 0xb73dacac>]
>>>

Для стандарта регистр не имеет значения, а для модулей и для человека - имеет.

По стандарту это вообще вот так выглядит
<?xml version="1.0" encoding="UTF-8"?><document><number>00000025</number><date>2016-02-04</date></document>
Так вот длинные документы вообще невозможно читать, если они генерятся программой.

Все переносы строк, как и регистр в тегах, - это для удобного чтения человеком. Если там всё это есть, то есть вероятность, что это писал человек для человека. То есть нужно бы всё это сохранить, а то вдруг это кто-то уже давно читает.

FishHook
<NUMBER>26</NUMBER>
И почему у тебя там 26? Ведь 00000025, как и 26, - это не число, а текстовая строка.



Отредактировано py.user.next (Май 6, 2016 08:21:46)

Офлайн

#9 Май 6, 2016 08:16:07

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

FishHook
то я снимаю шляпу
Снимайте шляпу.
1. Ваш вариант неправильно транслирует лидирующие нули (что легко поправить).
2. Вариант py.user.next явно короче чем ваш. (что для такого объема кода правда не очень важно).
3. Все зависит от применения. Если это конфиг который предназначен для ручного редактирования, и скрипт это автоматизация процесса то ваш вариант убъет “любимое” форматирование пользователя, что в большинстве случаев недопустимо.
4. По поводу быстрее. Сейчас не проверял, но на больших xml - десятки мегабайт регулярные выражения оказывались 10-100 раз быстрее. Хотя тут наверное стоит актуализировать эти знания. Для такого файлика это не важно.

Да и xpath обычно ничуть не проще регулярного выражения. Однако надо отметить, что надежность регулярки конечно ниже (все на совести автора регулярного выражения).

Спору нет lxml полезный инструмент для работы с xml. Однако все эти пляски, гора кода и баталии порождены именно применением xml, который для хранения двух простых полей явно плохо подходит.



Отредактировано doza_and (Май 6, 2016 08:20:58)

Офлайн

#10 Май 6, 2016 08:25:31

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Увеличение на единицу в текстовом файле

doza_and
Да и xpath обычно ничуть не проще регулярного выражения. Однако надо отметить, что надежность регулярки конечно ниже (все на совести автора регулярного выражения).
Не только на совести автора регекспа, может быть и так впоследствии
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<!-- <NUMBER>00000025</NUMBER> -->
<NUMBER>00000030</NUMBER>
<Date>2016-02-04</Date>
</Document>
отчего разбор xml и спасает.



Отредактировано py.user.next (Май 6, 2016 08:27:07)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version