2015-11-23 2 views
3

мне нужно проверить строку, которая должна соответствовать:Regex для проверки повторения

1,2,3,4,5,6,7

Так правила: только одно число между 1 и 7, запятая разделитель, но я не хочу повторяться, так что это не законно, чтобы написать:

1,2,3,1,5

в настоящее время я использую:

([1-7]{1},){1,6}([1-7]{1}) 

Как я могу изменить его, чтобы проверить повторение?

+2

Почему вы хотите сделать использование регулярных выражений для этого? Я думаю, что регулярное выражение будет возможным, но имеет сложность O (N^2). Просто используйте цикл и набор замеченных значений. –

+0

Потому что я хочу строго проверить вход пользователя. – greywolf82

+0

Regex действительно не очень хорошо оценивает.Разделите и проверьте полученный массив для дубликатов, если сможете. В противном случае вам понадобится негативный внешний вид для каждой группы захвата и очень грязное регулярное выражение. – adamdc78

ответ

2

Я думаю, что @tobias_k находится на правильном пути, предполагая, что это хорошая стратегия для проверки строк, которые имеют повторение, но я думаю, что вы можете иметь более полное регулярное выражение, которое ограничивает класс символов и разделитель, как вам требуется ,

Обновление: Эта версия проверяет наличие нескольких цифр.

([1-7]{1})(?:[1-7,])*\1|[^1-7,]+
([1-7]{1}),(?:[1-7]{1},)*(?:\1|[^1-7,]|(?:[1-7]{2,}))

1,2,3,4,5,6,7 // PASS: no match 
1,2,3,4,5,6,8 // FAIL: matches out-of-bounds digit '8' 
1,2,3,four,5,6,7 // FAIL: matches non-integer 'four' 
1,2,3,1,5  // FAIL: matches repeating digit '1' 
1,2,3,45   // FAIL: matches multiple digits 

Syntax diagram via regexper.com

+1

Кажется, что это выражение не совпадает с 1,2,3,45 – greywolf82

+1

@ greywolf82 Хороший улов. Я обновил RegEx, чтобы проверить наличие множественных цифровых значений. Это было немного сложно сделать, но использование генератора синтаксических диаграмм очень помогло. Я включил сгенерированную диаграмму со ссылкой на генератор Regexper.com. – gfullam

3

Вы можете использовать \1 для ссылки на ранее подобранную группу (первая группа в этом случае). Используйте это, чтобы найти строки, которые имеют повторения.

Регулярное выражение может выглядеть следующим образом: .*\b(\d+)\b.*\b\1\b

  • .* ничего
  • \b(\d+)\b число между разделителями слов (группа 1)
  • .* больше ничего
  • \b\1\b группа 1 раз между словом разделителей

Пример в Python:

>>> p = r".*\b(\d+)\b.*\b\1\b" 
>>> re.match(p, "1,2,3,4,5,6,7") 
None 
>>> re.match(p, "1,2,3,1,5") 
<_sre.SRE_Match object at 0x8d2c2a0> 

Это не будет проверять эти запятые, хотя, так что вам придется сделать это в два этапа: сначала проверить общую компоновку, затем отфильтровать тех, с повторениями.

Обратите внимание, однако, что выполнение этого, вероятно, не будет хорошим: он должен попробовать каждое число для первой группы, а затем сопоставить строку, чтобы увидеть, есть ли другая группа, которая совпадает с первой, затем backtrack и повторите попытку, задав эту сложность O (n²). Вместо этого я предлагаю просто использовать набор уже увиденных чисел и цикл.

+0

Это работает в обратном порядке, сопоставляя строки-нарушители, а не соответствующие строкам. Он также не учитывает другое правило OP: «только одно число от 1 до 7», так что это проходит: «1,2,3,4,5,6,8' И поскольку он использует« любой символ », '.' (точка), это проходит:« 1,2,3, четыре, 5,6,7'. – gfullam

+0

@gfullam Да, вот почему я сказал использовать это, чтобы найти строку, которая повторяла _have_, и указала, что ему понадобится другое регулярное выражение для проверки общего макета. –

+0

Вы правы, что это хорошая стратегия для проверки строк, которые * имеют * повторение, но я чувствую, что это все еще немного короче. Я не думаю, что вам нужен второй проход. Возможно более полное регулярное выражение. – gfullam