Как сопоставить и извлечь номер и заголовок раздела в python?

Я хочу сопоставить и извлечь номера и заголовки разделов и подразделов в любом из следующих форматов:

section
1 section
2. section
2.1 subsection
2.1.1 subsection
2.1.1. subsection
2.1.1. subsection multiple words less than 40 chars

Я пытался

^(\d{1,3}?(\.?\d{1,3}?\.?)*)?\s*(\w*)$

Не совпадает со вторым. Я также предпочитаю иметь две желаемые группы (номер раздела и название раздела)

Вы ожидаете, что он будет соответствовать 1-3 цифрам, где за 2. следует 0 цифр, поэтому я думаю, что \d{0,3} сработает. Обратите внимание, что в настоящее время, поскольку все квантификаторы являются необязательными, он также будет соответствовать пустой строке, использование \w+ предотвратит это. Или лайкните ^(?:\d{1,3}\.?(?:\d{1,3}\.?)* )?[^\W\d]+regex101.com/r/oJ6R2D/1

The fourth bird 24.12.2020 13:09

С 2 группами ^(?:(\d{1,3}\.?(?:\d{1,3}\.?)*)?) ?([^\W\d]+)regex101.com/r/oxY99s/1

The fourth bird 24.12.2020 13:21

@Thefourthbird, как я могу изменить ваше предложение, если название раздела может состоять из одного или нескольких слов (буквенно-цифровых) и общей длины от 5 до 40. Я пробовал ^(?:(\d{1,3}\.?(?:\d{1,3}\.?)*)?) ?([^\W\s\d]{5,40})$, но не соответствует «1 разделу раздела»

Ahmad 24.12.2020 13:52

Если вы не хотите сопоставлять только пробелы ^(?:(\d{1,3}\.?(?:\d{1,3}\.?)*)?) ?(\w[\w \t]{4,39})regex101.com/r/Oa5AI5/1 или используйте [\w\s]{4,39}, но \s также может соответствовать новой строке

The fourth bird 24.12.2020 14:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
310
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Первый может быть частным случаем, но обычно .split() дает вам именно то, что вы хотите:

toc = '''\
section
1 section
2. section
2.1 subsection
2.1.1 subsection
2.1.1. subsection
2.1.1. subsection multiple words less than 40 chars'''

for line in toc.split('\n'):
    l = line.split(' ', 1)
    print(l)

Выход:

['section']
['1', 'section']
['2.', 'section']
['2.1', 'subsection']
['2.1.1', 'subsection']
['2.1.1.', 'subsection']
['2.1.1.', 'subsection multiple words less than 40 chars']
Ответ принят как подходящий

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

^(\d{1,3}\.?(?:\d{1,3}\.?)*)? ?([^\W\d]+)
  • ^ Начало строки
  • ( Группа захвата 1
    • \d{1,3}\.?(?:\d{1,3}\.?)* Сопоставьте 1-3 цифры, за которыми следуют части с . и 1-3 цифры
  • )? Закрыть группу и сделать ее необязательной
  • ? Сопоставьте необязательный пробел
  • ([^\W\d]+) Захватите группу 2, сопоставьте 1+ раз слово char без цифр

Демонстрация регулярных выражений | Демонстрация Python

import re

regex = r"^(\d{1,3}\.?(?:\d{1,3}\.?)*)? ?([^\W\d]+)"

s = ("section\n"
    "1 section\n"
    "2. section\n"
    "2.1 subsection\n"
    "2.1.1 subsection\n"
    "2.1.1. subsection")

print(re.findall(regex, s, re.MULTILINE))

Выход

[
    ('', 'section'),
    ('1', 'section'),
    ('2.', 'section'),
    ('2.1', 'subsection'),
    ('2.1.1', 'subsection'),
    ('2.1.1.', 'subsection')
]

Если вы хотите сопоставить 5-40 символов в группе 2, включая цифры, вы можете начать сопоставление с символа слова, чтобы он соответствовал хотя бы одному символу слова, и повторить, например, разрешенные символы 4-39 раз в классе символов.

^(\d{1,3}\.?(?:\d{1,3}\.?)*)? ?(\w[\w \t]{4,39})

Демонстрация регулярных выражений

Другие вопросы по теме