Как можно создать паттерн для библиотеки re, чтобы первая группа данных не повторялась, а вторая группа могла повторяться?

Как улучшить структуру и ясность моего вопроса о разбиении строки в Python? У меня есть строка, заданная следующим образом:  
<pre><code class="python">string = '60\napple\nbanana\ntomato\ncucumber\n120\nsofa\ntable'</code></pre>  
В этой строке присутствует число, после которого следуют названия овощей и фруктов, каждое из которых заканчивается символом переноса строки '\n'. Мне необходимо разделить эту строку, но предложенный паттерн:  
<pre><code class="python">taken = re.findall(r'[0-9]+\n(.+\n)+', string=string)</code></pre>  
не дает нужного результата. Я понимаю, что символ '+' в регулярных выражениях указывает на 1 и более повторений, но как правильно применить этот оператор к внутреннему паттерну? Возможно, предпочтительнее будет использовать метод:  
<pre><code class="python">re.split('\n', string=string)</code></pre>  
для решения этой задачи?
  • 30 марта 2025 г. 17:44
Ответы на вопрос 2
Для решения вашей задачи можно использовать библиотеку `re`, чтобы разделить строки на основе заданного формата: число, за которым следует список объектов (овощей или фруктов). Для этого вам нужно создать регулярное выражение, которое будет соответствовать одному числу и, возможно, нескольким строкам названий.

Ваш текущий паттерн `re.findall(r'[0-9]+\n(.+\n)+', string=string)` не даст нужный результат, потому что он пытается найти группу, которая включает в себя все строки, начиная с первого овоща, что делает результаты неудобными для работы. Вместо этого мы можем использовать паттерн, который будет соответствовать числу, а затем последующим объектам, записанным через перенос строки.

### Вот улучшенный подход:

В качестве первого шага, давайте изменим ваше регулярное выражение. Мы можем использовать `re.findall`, чтобы найти число и соответствующее ему количество строк. В данном случае, нам понадобится использовать захватывающую группу и квантификатор `*` для повторяющихся строк:

```python
import re

string = '60\napple\nbanana\ntomato\ncucumber\n120\nsofa\ntable'

# Используем re.findall с двумя группами
pattern = r'(\d+)\n((?:[^\n]+\n)*)'
matches = re.findall(pattern, string)

# Обрабатываем найденные данные
result = [(int(number), items.strip().split('\n')) for number, items in matches]

print(result)
```

### Объяснение паттерна:

- `(\d+)`: это первая группа, которая захватывает число.
- `\n`: символ новой строки, который следует за числом.
- `((?:[^\n]+\n)*)`: это вторая группа (не захватывающая), которая захватывает любое количество строк (овощей или фруктов), завершающихся символом новой строки. Здесь мы используем `(?:...)`, чтобы сделать группу не захватывающей, и `*`, чтобы указать возможность повторений, включая ноль.

### Результат:

Запустив данный код, вы получите список кортежей, где каждый кортеж содержит число и список названий, например:

```
[(60, ['apple', 'banana', 'tomato', 'cucumber']),
 (120, ['sofa', 'table'])]
```

### Альтернативный подход:

Вы также правы в том, что использование `re.split('\n', string=string)` может быть полезным для простой разбивки строки на строки. Если вы хотите получить группы по числам непосредственно, вы можете просто разбить строку, а затем обработать элементы:

```python
lines = string.strip().split('\n')
result = []

for i in range(0, len(lines), 5):  # Предполагаем, что каждая группа состоит из числа и 4 названий
    number = int(lines[i])
    items = lines[i+1:i+5]  # Считываем следующие 4 строки
    result.append((number, items))

print(result)
```

Этот подход может быть проще, если вы заранее знаете структуру данных.
Честно сказать не совсем понял, что в итоге ты хочешь сделать. Предположу что объеденить числа и фрукты в одну группу и собрать все такие группы. 
taken = re.findall(r'([0-9]+\D+)', string=string)
затем легко, удалить лишние символы даже обычным питоном.
Похожие вопросы