正则表达式匹配我的单词模式,野性字符

时间:2010-11-02 19:34:24

标签: ruby regex

你能帮我解决这个问题:

我希望我的Ruby程序使用正则表达式来匹配具有以下模式的单词

模式有

  1. 字母列表(例如,ABCC => 1A,1B,2C)
  2. N Wild Card Charaters(N可以是0或1或2)
  3. 固定字(例如“XY”)。
  4. 规则:

    1. 关于字母列表,它应与

      字匹配

      一个。 0或1 A

      湾0或1 B

      ℃。 0或1或2 C

    2. 根据N的值,可以有0或1或2个野生字符
    3. 固定字始终按照给定的顺序排列。
    4. 所有这些的组合可以是任何顺序,并且应该与下面的单词匹配
    5. ABWXY(如果野性char = 1)

      BAXY

      CXYCB

      但不是带有2个A或2个B的单词

      我使用的模式如^ [ABCC] *。XY $

      但它会查找超过1 A,或1 B或2 C的单词,并且还会查找以XY结尾的单词,我希望所有单词在任何地方都有XY,字母和野性字符在任何位置。< / p>

4 个答案:

答案 0 :(得分:2)

如果它是正则表达式,可以使用以下内容:

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 :(得分:1)

你需要正确地打破你的模式。在regexp术语中,[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

答案 2 :(得分:1)

我认为自己在正则表达方面相当不错,我想不出办法去做你所要求的。正则表达式寻找模式,你似乎想要的是不同的模式。在您的情况下,编写一个函数可能更合适,该函数将字符串拆分为字符并计算您拥有的内容,以便您可以满足您的条件。

仅举一个问题的例子,像/ [abc] /这样的正则表达式将匹配a,b和c的每一次出现,无论这些字母出现在字符串中的次数是多少。您可以尝试/ c {1,2} /,它将匹配“c”,“cc”和“ccc”。它匹配最后一种情况,因为你在“ccc”中有一个1 c和2 c的模式。

我在开发和调试正则表达式时发现的一件事是rubular.com。尝试一些例子,我想你会看到你的反对意见。

我不知道这是否真的有任何帮助,但它可能会帮助您选择方向。

答案 3 :(得分:1)

由于您希望允许这些“元素”以任何顺序出现,您最好编写一些从头到尾遍历字符串的Ruby代码,并计算As,B和C的数量,发现它是否包含您想要的子字符串。如果As,Bs和Cs的数量在你想要的限制内,并且它包含所需的子字符串,并且它的长度(即字符数)等于所需子字符串的长度,加上As的数量,加上B的数量加上C的数量,加上最多N个字符,那么字符串就好了,否则就不好了。实际上,要小心,首先应搜索所需的子字符串,然后从原始字符串中删除,然后计算As,B和C的数量,否则您可能会无意中计算As, Bs和Cs出现在你想要的字符串中,如果有的话。

你可以用正则表达式做你想做的事,但这将是一个漫长丑陋的正则表达式。为什么?因为对于元素的每个可能的顺序,在正则表达式中需要单独的“case”。例如,正则表达式“^ ABC..XY $”将匹配任何以“ABC”开头并以“XY”结尾且中间有两个外卡字符的字符串。但只是按顺序。如果您想要所有可能订单的正则表达式,则需要在正则表达式中列出所有这些订单,例如它将开始像“^(ABC..XY | ACB..XY | BAC..XY | BCA..XY |”之类的东西,并从那里开始,大约5!= 120个不同的5个元素列表,那么对于没有A的情况你需要更多,对于没有B的情况需要更多,等等。我认为正则表达式是这里工作的错误工具。