Регулярное выражение, чтобы соответствовать моему шаблону слов, диких символов - PullRequest
0 голосов
/ 02 ноября 2010

Вы можете помочь мне с этим:

Я хочу, чтобы регулярное выражение для моей программы Ruby соответствовало слову с шаблоном ниже

Шаблон имеет

  1. Список букв (например. ABCC => 1 A, 1 B, 2 C)
  2. N символов Wild Card (N может быть 0 или 1 или 2)
  3. Фиксированное слово (например, «XY»).

Правила:

  1. Что касается списка букв, он должен соответствовать словам с

    а. 0 или 1 A

    б. 0 или 1 B

    с. 0 или 1 или 2 C

  2. На основании значения N может быть 0, 1 или 2 диких символа.
  3. Фиксированное слово всегда в указанном порядке.
  4. Комбинация всех этих может быть в любом порядке и должна соответствовать словам как ниже

ABWXY (если дикий символ = 1)

BAXY

CXYCB

Но не слова с 2 A или 2 B

Я использую шаблон как ^ [ABCC] *. XY $

Но он ищет слова с более чем 1 A или 1 B или 2 C, а также ищет слова, которые заканчиваются на XY, я хочу, чтобы все слова имели XY в любом месте и буквы и дикие символы в любом положении.

Ответы [ 4 ]

2 голосов
/ 03 ноября 2010

Если оно должно быть регулярным выражением, можно использовать следующее:

if subject =~ 
    /^                          # start of string
    (?!(?:[^A]*A){2})           # assert that there are less than two As
    (?!(?:[^B]*B){2})           # and less than two Bs
    (?!(?:[^C]*C){3})           # and less than three Cs
    (?!(?:[ABCXY]*[^ABCXY]){3}) # and less than three non-ABCXY characters
    (?=.*XY)                    # and that XY is contained in the string.
    /x

    # Successful match
else
    # Match attempt failed
end

Это предполагает, что ни один из символов A, B, C, X или Y не допускается в качестве подстановочных знаков.

1 голос
/ 03 ноября 2010

Я считаю себя неплохо справляться с регулярными выражениями и не могу придумать, как сделать то, что вы просите.Регулярные выражения ищут шаблоны, а то, что вам нужно, - это довольно много разных шаблонов.В вашем случае было бы более уместно написать функцию, которая разбивает строку на символы и считает то, что у вас есть, чтобы вы могли удовлетворять вашим критериям.

Просто чтобы привести пример вашей проблемы, регулярное выражение типа / [abc] / будет соответствовать каждому вхождению a, b и c независимо от того, сколько раз эти буквы появляются в строке.Вы можете попробовать / c {1,2} /, и он будет соответствовать "c", "cc" и "ccc".Это соответствует последнему случаю, потому что у вас есть шаблон 1 c и 2 c в "ccc".

Одна вещь, которую я нашел неоценимой при разработке и отладке регулярных выражений, - rubular.com Попробуйте несколько примеров, и я думаю, вы увидите, с чем вы столкнулись.

Я не знаю, действительно ли это поможет вам, но это может помочь вам выбрать направление.

1 голос
/ 03 ноября 2010

Поскольку вы хотите, чтобы эти "элементы" появлялись в любом порядке, вам лучше написать немного кода на Ruby, который просматривает строку от начала до конца и считает количество As, Bs и Cs,находит, содержит ли она желаемую подстроку.Если число As, Bs и Cs находится в желаемых пределах и содержит искомую подстроку, а ее длина (то есть количество символов) равна длине искомой подстроки плюс число As, плюсКоличество символов B, плюс количество символов C, плюс не более N символов, более того, тогда строка хорошая, в противном случае она плохая.На самом деле, чтобы быть осторожным, вы должны сначала найти нужную подстроку, а затем удалить ее из исходной строки, а затем подсчитать количество As, Bs и Cs, поскольку в противном случае вы можете непреднамеренно подсчитать As, Bи C, которые появляются в нужной вам строке, если они там есть.

Вы можете делать то, что хотите, с помощью регулярного выражения, но это будет длинное уродливое регулярное выражение.Зачем?Потому что вам понадобится отдельный «регистр» в регулярном выражении для каждого из возможных порядков элементов.Например, регулярное выражение «^ ABC..XY $» будет соответствовать любой строке, начинающейся с «ABC» и заканчивающейся «XY» и имеющей два символа подстановки в середине.Но только в таком порядке.Если вам нужно регулярное выражение для всех возможных порядков, вам нужно перечислить все эти порядки в регулярном выражении, например, оно должно начинаться примерно так: «^ (ABC..XY | ACB..XY | BAC..XY |BCA..XY | "и дальше, примерно с 5! = 120 различными порядками для этого списка из 5 элементов, тогда вам понадобится больше для случаев, когда не было A, а затем больше для случаев, когда не былоB и т. Д. Я думаю, что регулярное выражение - неподходящий инструмент для этой работы.

1 голос
/ 02 ноября 2010

Вам нужно правильно оформить свой шаблон. В терминах регулярного выражения [ABCC] означает «любой из A, B или C», где дубликат C игнорируется. Это оператор множества, а не оператор группировки, такой как ().

То, что вы, похоже, описываете, создает регулярное выражение на основе параметров. Вы можете сделать это, передав строку Regexp.new и используя результат.

Пример примерно такой:

def match_for_options(options)
  pattern = '^'

  pattern << 'A' * options[:a] if (options[:a])
  pattern << 'B' * options[:b] if (options[:b])
  pattern << 'C' * options[:c] if (options[:c])

  Regexp.new(pattern)

конец

Вы бы использовали что-то вроде этого:

if (match_for_options(:a => 1, :c => 2).match('ACC'))
  # ...
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...