LINUX.ORG.RU

Помогите с регулярочкой, кому не сложно)).

 


0

6

Задача такая. Есть некая строка. Надо одной регуляркой(двумя я сам могу) проверить:

  1. строка начинается и заканчивается буквой.
  2. строка не содержит подряд 3 цифры.

Пример: a12b1с - строка хорошая.

a123b - плохая.

1аа2в - плохая.

Если есть гуру. Помогите, пожалуйста.

Какое-то извращение. Через полгода сами такую регулярку не поймёте, понадобится что-то поправить, будет в ступоре. Плюс, сразу уточняйте какая регулярка — базовая, расширеная, перловая и т.д.

ИМХО, для задач подобного уровня chatGPT хорошо подходит.

mky ★★★★★
()
Ответ на: комментарий от wandrien

Вот, почему регулярки это боль.

Это просто, говорят они, это не сложнее обычных вилдкард. И как только начинаешь в это верить, то появляется какая-нибудь отрицательная ретроспективная проверка.

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

Просто нехрен ставить такие задачи)

Это не проблема инструмента. А известная проблема применения инструмента: «когда в руках молоток, то всё кажется гвоздями».

wandrien ★★
()

Спрошу chatgpt за тебя

Для проверки указанных условий можно использовать следующую регулярную expression:

```
^[a-zA-Z][a-zA-Z0-9]*(?<!\d)(?<!\d\d\d)[a-zA-Z]$
```

Разберем по частям:

- `^` - начало строки
- `[a-zA-Z]` - одна буква (строка начинается с буквы)
- `[a-zA-Z0-9]*` - любое количество букв или цифр
- `(?<!\d)(?<!\d\d\d)` - проверка на отсутствие подряд 3 цифр
- `[a-zA-Z]` - одна буква (строка заканчивается буквой)
- `$` - конец строки

Таким образом, данная регулярная выражение позволяет проверить два условия одновременно: начало и конец строки содержат буквы и нет подряд 3 цифр.

anonymous_sapiens ★★★★★
()
Последнее исправление: anonymous_sapiens (всего исправлений: 1)

перечитываем условие в удобный вид, например: строка начинается с букв, далее следуют группы {1-2 цифры}{более одной буквы}; можете предварительно нарисовать граф.

что-то типа такого получится: [[:alpha:]]+([[:digit:]]{1,2}[[:alpha:]]+)*

MKuznetsov ★★★★★
()
import re


def test (s):
    pattern = r"""(?x)
    (
      # Строки длинной от 0 до 4 символов включительно:
      # Если первый и последний символ - буквы,
      # то остальные символы не имеют значения, 
      # т.к. их не более 2 и запрет на наличие 3 
      # чисел подряд не будет нарушен:
      ([^\d]{,2} | [^\d].{1,2}[^\d]) |
      # Строки длинной 5 и более символов:
      # Помимо условия о первом и последнем символах -
      # буквах здесь теперь необходимо учесть, какие
      # символы находятся между ними
      (
        [^\d]
        ( 
          # Сначала рассмотрим группы по 3 символа.
          # Чтобы исключить возможность попадания
          # 3 чисел подряд на стыке 'троек' символов
          # используем negative lookbehind assertion.
          # Также необходимо учесть, что между первым
          # и последним символом строки м.б. число символов, 
          # не кратное 3, поэтому затем также рассмотрим 
          # группы из 2 и 1 символов:
          # --- 1 буква 2 числа ---
          [^\d]\d{2} | 
          (?<!\d{2})\d[^\d]\d | 
          (?<!\d{1})\d{2}[^\d] |
          # --- 2 буквы 1 число ---
          [^\d]{2}\d |
          [^\d]\d[^\d] |
          (?<!\d{2})\d[^\d]{2} |
          # --- 3 или меньше букв ---
          [^\d]{,3} |
          # --- 1 буква и 1 число ---
          (?<!\d{2})\d[^\d] |
          [^\d]\d |
          # --- 1 число ---
          (?<!\d{2})\d
        )+
        [^\d]
      )
    )
    """
    print("Хорошая" if re.fullmatch(pattern, s) else "Плохая")
endless__autumn
()
Ответ на: комментарий от wandrien

Я подписался, потому что в голове был такой же паттерн, но не хотел без проверки писать, а проверять было некогда. ) Стало любопытно, кто что ответит в итоге.

emorozov
()
Ответ на: комментарий от DarkAmateur

ему нужно r1 & !r2

Можно же переформулировать наоборот, т.е. первая не буква, или последняя не буква, или есть 3 цифры.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от DarkAmateur

Ты просто инвертировал другую половину условия

или есть 3 цифры.

(это то же самое, что «есть 3 и более цифры») инвертируем условие, получается «цифры встречаться могут, но не более двух подряд».

Ты так и сделал.

Shushundr ★★★
()
Последнее исправление: Shushundr (всего исправлений: 1)
Ответ на: комментарий от Shushundr

Ты просто инвертировал другую половину условия

А no-such-file предлагал инвертить всё выражение, т.е. решать задачу «от противного» целиком.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 4)

Я хренею с вас, дорогая редакция.

Что дано в задании:

строка начинается и заканчивается буквой.

Что пытаются делать кодыри в целях «оптимизации»:

строка начинается и заканчивается не цифрой

А потом еще удивляемся, откуда столько дыр и багов в программах.

wandrien ★★
()
Ответ на: комментарий от DarkAmateur

это не только буквы, но и спец. символы и пробелы

Во-первых так можно прикопаться и к понятию «буква». А во-вторых, что не так? Да, любая не буква, в т.ч. пробел и т.п. по условию это отрицательное совпадение и «плохая» строка.

no-such-file ★★★★★
()