Я хочу сопоставить и извлечь номера и заголовки разделов и подразделов в любом из следующих форматов:
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*)$
Не совпадает со вторым. Я также предпочитаю иметь две желаемые группы (номер раздела и название раздела)
С 2 группами ^(?:(\d{1,3}\.?(?:\d{1,3}\.?)*)?) ?([^\W\d]+)
regex101.com/r/oxY99s/1
@Thefourthbird, как я могу изменить ваше предложение, если название раздела может состоять из одного или нескольких слов (буквенно-цифровых) и общей длины от 5 до 40. Я пробовал ^(?:(\d{1,3}\.?(?:\d{1,3}\.?)*)?) ?([^\W\s\d]{5,40})$
, но не соответствует «1 разделу раздела»
Если вы не хотите сопоставлять только пробелы ^(?:(\d{1,3}\.?(?:\d{1,3}\.?)*)?) ?(\w[\w \t]{4,39})
regex101.com/r/Oa5AI5/1 или используйте [\w\s]{4,39}
, но \s
также может соответствовать новой строке
Первый может быть частным случаем, но обычно .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})
Вы ожидаете, что он будет соответствовать 1-3 цифрам, где за 2. следует 0 цифр, поэтому я думаю, что
\d{0,3}
сработает. Обратите внимание, что в настоящее время, поскольку все квантификаторы являются необязательными, он также будет соответствовать пустой строке, использование\w+
предотвратит это. Или лайкните^(?:\d{1,3}\.?(?:\d{1,3}\.?)* )?[^\W\d]+
regex101.com/r/oJ6R2D/1