Конференция "Прочее" » Может ли кто помочь с Regular Expression?
 
  • Empleado © (22.01.18 13:51) [0]
    Задача такая:

    Дано: Конечный набор слов. Слова короткие, от 2 до 4 букв.
    Например: АБС, ДДФ, ЯС, ОПП, ШЦЦР, ССД
    Эти слова используются пользователями при задании определенных характеристик.

    Необходимо:
    составить фильтр RexExp, который позволяет пользователю вводить слова из заданного набора, и только из этого набора, в любой их последовательности. Разделитель слов - только запятая.
    Слова могут повторяться (это не важно). Наличие, положение и количество пробелов неважно.

    Например, пользователь может набрать в поле ввода:
    АБС, ОПП,ЯС (= ОК)
    или
    ШЦЦР (= ОК)
    или АБС, ККК, ШЦЦР, ССД (= НЕ ОК)

    Спасибо за любую инфу/решение.

    ПС. Сегодня используется просто: в RexExp стоит "АБС|ДДФ| ЯС|ОПП|ШЦЦР|ССД|,", что соответственно не соответствует заданию.
  • anetE10 © (22.01.18 15:09) [1]
    одной регуляркой делать смысла нет.
    так как она будет словарем
    а лучше иметь как словарь

    то есть сначала сплит по разделителю, потом цикл на отсутствие в словаре.
    если хотя бы одного элемента нет, значит не Ок
  • DayGaykin © (22.01.18 15:30) [2]
    Ну и что ты хочешь?
  • Empleado © (22.01.18 17:56) [3]
    >одной регуляркой делать смысла нет.
    К сожалению, в моем распоряжении только одно поле (на уже готовом продукте, код не редактируется), где можно ввести только одно (но длинннооеее) регулярное выражение, которое говорит пользователю: Введенные данные соответствуют, или не соответствуют требованиям.

    >DayGaykin ©   (22.01.18 15:30) [2]
    А цель, товарищ Гайкин, проста:
    задать вышеупомянутые требования таким образом, чтобы не дать возможность нашему пользователю вводить слова, которые не встречаются в заранее установленном списке.

    Спасибо.
  • Внук © (22.01.18 20:33) [4]
    Тестовую программу писать было лень, поэтому тестировал в оракле.
    Вот такое выражение вроде работает
    select 1 from dual where regexp_like('ABC, DEF', '^[ ]*(ABC|DEF)(\s*,\s*(ABC|DEF))*$');

    То есть паттерн '^[ ]*(ABC|DEF)(\s*,\s*(ABC|DEF))*$'
    где вместо ABC|DEF надо перечислить реальные допустимые значения. Да, перечислить придется в двух местах. Наверно, можно как-то проще, со ссылкой на предыдущее совпадение, но я не стал.
  • Внук © (22.01.18 20:35) [5]
    Между квадратными скобками - один пробел. Вместо \s надо тоже поставить пробелы на самом деле
  • Внук © (22.01.18 20:38) [6]
    Если хочется допустить и конечные пробелы, то так
    '^[_]*(ABC|DEF)(_*,_*(ABC|DEF))*_*$'
    где символом _ обозначен пробел.
  • xayam © (22.01.18 20:39) [7]

    > Введенные данные соответствуют, или не соответствуют требованиям.

    а зачем эта предобоработка если можно постфактум проверить (все равно придется) перед добавлением в базу например так и делают
  • xayam © (22.01.18 20:41) [8]
    или вообще если есть список то дать пользователю возможность несколько раз выбрать слово из списка и добавлять программно эти слова в ридонли поле (примерно так в веб и делают)
  • xayam © (23.01.18 01:34) [9]
    хотя если нет исходников, то вообще видимо только через регэкспы как то извращаться :)
  • xayam © (23.01.18 09:56) [10]

    > То есть паттерн '^[ ]*(ABC|DEF)(\s*,\s*(ABC|DEF))*$'
    > где вместо ABC|DEF надо перечислить реальные допустимые
    > значения. Да, перечислить придется в двух местах. Наверно,
    >  можно как-то проще, со ссылкой на предыдущее совпадение,
    >  но я не стал.

    чего-то я не понял зачем в двух местах
    можно так:
    ^(\s*(АБС|ДДФ|ЯС|ОПП|ШЦЦР|ССД)\s*,?\s*)*$

    вот на тестере работает
    https://www.regextester.com/?fam=100076
  • xayam © (23.01.18 10:01) [11]

    > чего-то я не понял зачем в двух местах
    > можно так:
    > ^(\s*(АБС|ДДФ|ЯС|ОПП|ШЦЦР|ССД)\s*,?\s*)*$

    здесь неправильно. Если в обязательном порядке нужен разделитель то так:
    ^(\s*(АБС|ДДФ|ЯС|ОПП|ШЦЦР|ССД)\s*(,| |$)\s*)*$
  • xayam © (23.01.18 10:23) [12]
    или с плюсиком в конце если обязательно присутствие хотя бы одной характеристики...
    вообще и пробел можно удалить:
    ^(\s*(АБС|ДДФ|ЯС|ОПП|ШЦЦР|ССД)\s*(,|$)\s*)+$
  • Внук © (23.01.18 10:52) [13]
    Потому что если не два раза, то строка
    АБС, ДДФ, ЯС, ОПП, ШЦЦР, ССД ССД,
    (с запятой в конце и с пропущенной запятой между значениями) тоже подходит
  • DayGaykin © (23.01.18 10:56) [14]
    ^((^|(?<!^),)\s*(АБС|ДДФ|ЯС|ОПП|ШЦЦР|ССД)\s*)+$
  • DayGaykin © (23.01.18 10:58) [15]
  • xayam © (23.01.18 11:15) [16]

    > Внук ©   (23.01.18 10:52) [13]
    > Потому что если не два раза, то строка
    > АБС, ДДФ, ЯС, ОПП, ШЦЦР, ССД ССД,
    > (с запятой в конце и с пропущенной запятой между значениями)
    > тоже подходит

    вроде не подходит
    https://www.regextester.com/?fam=100078
  • xayam © (23.01.18 11:17) [17]

    > DayGaykin ©   (23.01.18 10:56) [14]
    > ^((^|(?<!^),)\s*(АБС|ДДФ|ЯС|ОПП|ШЦЦР|ССД)\s*)+$
    > DayGaykin ©   (23.01.18 10:58) [15]
    > https://regex101.com/r/8gR2xG/1

    согласен так лучше чем у меня
  • Внук © (23.01.18 13:15) [18]

    > DayGaykin ©   (23.01.18 10:56) [14]

    Да.
    К сожалению, оракл такого не умеет, а про сайт https://regex101.com я не знал :)
  • Empleado © (23.01.18 16:07) [19]
    Внук, DayGaykin, Xayam, Большое Спасибо!
    Все заработало как надо.

    Блин, оказывается это целая наука!!!
  • xayam © (23.01.18 16:29) [20]

    > Блин, оказывается это целая наука!!!

    вот советую почитать на тему
    https://rutracker.org/forum/viewtopic.php?t=3828631

    DayGaykin хорошо сделал регэксп, в книге как раз подобные случаи рассматриваются
    я то давно читал уже забыл этот просмотр назад с условием
  • Empleado © (23.01.18 16:52) [21]
    Спасибо!
 
Конференция "Прочее" » Может ли кто помочь с Regular Expression?
Есть новые Нет новых   [134430   +2][b:0][p:0.001]