Я пытаюсь извлечь некоторый контент из txt-файла (из преобразования PDF). Вы можете заметить пробел (или его отсутствие) после метки или перед номером_страницы, а иногда между номером_страницы и кодом X.Y.Z нет \n. Вот образец:
Summary
...
30. LOT 03 CLOS COUVERT.................... 29
30.1. LOT 03-1 ETANCHEITE .................... 29
30.1.1. Travaux divers.................... 29
30.1.1.1. Boite à eau.................... 29
30.1.1.2. Descentes d’eaux pluviales en façades .................30
30.1.1.3. Lanterneau de désenfumage...............30 30.1.1.4. Etanchéité résine..................31
...
Структура резюме такова:
X.Y.Z. Label ....................... Page_number
И позже в том же документе мы можем найти связанное описание:
30. LOT 03 CLOS COUVERT (no description here)
30.1. LOT 03-1 ETANCHEITE (no description here)
...
30.1.1.1. Boite à eau
Composition : -Descente d\’eaux pluviales
o en zinc naturel, épaisseur 0.80 mm
o en tle laquée jaune sur les zones d\’enduit jaune -Moignon cylindrique du diamètre de la descente EP -Trop-plein rectangulaire positionné sur face avant etc ...
30.1.1.2. Descentes d\’eaux pluviales en façades
Fourniture et pose de descentes d\'eaux en zinc extérieures type VM Zinc
...
Мой вариант использования — поместить метку XYZ в словарь Python в качестве ключей только из сводки и связать с ней описания. Ожидаемый результат выглядит так:
{ '30. LOT 03 CLOS COUVERT' : '',
'30.1. LOT 03-1 ETANCHEITE' : '',
...
'30.1.1.1. Boite à eau' : 'Composition : -Descente d’eaux pluviales
o en zinc naturel, épaisseur 0.80 mm
o en tle laquée jaune sur les zones d\’enduit jaune -Moignon cylindrique du diamètre de la descente EP -Trop-plein rectangulaire positionné sur face avant etc ...',
'30.1.1.2. Descentes d\’eaux pluviales en façades' : 'Fourniture et pose de descentes d\'eaux en zinc extérieures type VM Zinc...'}
Я попробовал это регулярное выражение, и это лучший результат, который я могу получить, но это не лучший результат:
(\d+[.])(.*)?[.]*\s*\d+
Моя проблема связана с управлением точками, извлечением меток и отсутствием \n.
Не могли бы вы меня вылечить?
После ? ставить (.*) нет смысла. * уже допускает совпадение нулевой длины, поэтому оно по своей сути необязательно.
Вы продолжаете говорить, что код X.Y.Z. Но примерные данные выглядят как W.X.Y.Z. Предполагается ли использовать в качестве ключа только первые три цифры?
Ни в одной из ваших образцовых линий нет Label :
Можете ли вы добавить к вопросу ожидаемый результат?
вы можете восполнить недостающие \n, сопоставив (^|\s) перед цифрами ключей.
Хорошо, запрос отредактирован, спасибо за отзыв! Я проверю все ваши предложения и отвечу правильным ;)






IIUC, вы можете использовать re.findall и (\d+(?:\.\d+)*\.) (.*?)\.* ?(\d+):
import re
txt = '''Summary
30.1.3.1. Boite à eau................................................................................................................................................. 29
30.1.3.2. Descentes d’eaux pluviales en façades ....................................................................................................30
30.1.3.3. Lanterneau de désenfumage.....................................................................................................................30 30.1.3.4. Etanchéité résine.......................................................................................................................................31 '''
out = re.findall(r'(\d+(?:\.\d+)*\.) (.*?)\.* ?(\d+)', txt)
out2 = {k: t for k, *t in out}
Выход:
# out
[('30.1.3.1.', 'Boite à eau', '29'),
('30.1.3.2.', 'Descentes d’eaux pluviales en façades ', '30'),
('30.1.3.3.', 'Lanterneau de désenfumage', '30'),
('30.1.3.4.', 'Etanchéité résine', '31')]
# out2
{'30.1.3.1.': ['Boite à eau', '29'],
'30.1.3.2.': ['Descentes d’eaux pluviales en façades ', '30'],
'30.1.3.3.': ['Lanterneau de désenfumage', '30'],
'30.1.3.4.': ['Etanchéité résine', '31']}
Если вы просто хотите, чтобы метки были ключами, а описания — значениями:
out = dict(re.findall(r'(\d+(?:\.\d+)*\.) (.*?)\.* ?\d+', txt))
Выход:
{'30.1.3.1.': 'Boite à eau',
'30.1.3.2.': 'Descentes d’eaux pluviales en façades ',
'30.1.3.3.': 'Lanterneau de désenfumage',
'30.1.3.4.': 'Etanchéité résine'}
спасибо за вашу помощь, но ваше регулярное выражение ведет себя странно (но оно лучше моего;)). Иногда этикетка обрезается, иногда добавляется часть описания (см. мое обновление), но не правильный код X.Y.Z : {'10.': 'Le choix des coloris se portera sur... '... }. Здесь «метка» неверна, поскольку значение dict является частью 40.5.2.2. описание. На этикетке должно быть «10. ЛОТ 01 VRD».
@A.Dumas ну, всегда сложно иметь полностью общее регулярное выражение, не зная всех угловых случаев. Рад, что вы нашли то, что вам помогло
Вы можете использовать две группы захвата, где первая группа — это ключ, а вторая группа — описание.
Если речь идет конкретно о точках, которые вы хотите опустить:
\b(\d+(?:\.\d+)*)\.[^\S\n]+([\s\S]*?)\.{2,}\s*\d+\b
Посмотрите демонстрацию регулярных выражений и демонстрацию Python
Пример
import pprint
import re
regex = r"\b(\d+(?:\.\d+)*)\.[^\S\n]+([\s\S]*?)\.{2,}\s*\d+\b"
s = ("> Summary\n"
"30.1.3.1. Boite à eau................................................................................................................................................. 29 \n"
"30.1.3.2. Descentes d’eaux pluviales en façades ....................................................................................................30 \n"
"30.1.3.3. Lanterneau de désenfumage.....................................................................................................................30 30.1.3.4. Etanchéité résine.......................................................................................................................................31")
pprint.pprint(dict(re.findall(regex, s)))
Выход
{'30.1.3.1': 'Boite à eau',
'30.1.3.2': 'Descentes d’eaux pluviales en façades ',
'30.1.3.3': 'Lanterneau de désenfumage',
'30.1.3.4': 'Etanchéité résine'}
Если вы хотите, чтобы вся часть включала точки прямо перед номером страницы, тогда значение группы 2 будет соответствовать до тех пор, пока либо новый ключ не начнется после номера страницы, ИЛИ пока это не будет последнее описание с номером страницы, за которым следует конец строки.
\b(\d+(?:\.\d+)*)\.[^\S\n]+([\s\S]*?)\s*\b(?=\d+\s*$|\d+\s+\d+(?:\.\d+)*\.)
Посмотрите демонстрацию регулярных выражений и демонстрацию Python
Большое спасибо ! ваше регулярное выражение отлично справляется со своей задачей. Я обновил свой вопрос, добавив несколько запросов;) (об описании). Если у вас есть идея, было бы приятно.
Здравствуйте, у меня та же проблема с этим шаблоном: «12.2.1.1.1.1 Порт à 1 Vantail 7 12.2.1.1.2 Блоки распределения 5 тест 7 «Я не могу адаптировать регулярное выражение «\b(\ d+(?:\.\d+)*)\.[^\S\n]+([\s\S]*?)\.{2,}\s*\d+\b" без точки между меткой и номер страницы. У вас есть идея? Спасибо
Я попытался исправить форматирование ввода. Но неясно, что на самом деле является частью файла: строка
> Summaryесть в файле или нет? И действительно ли оно включает в себя символ>. Пожалуйста, исправьте редактирование, если я ошибся.