匹配(不是x)和y(!x&y)的正则表达式

匹配(不是x)和y(!x&y)的正则表达式

我收到了一份带有谜题的桌面每日日历。其中一个难题是破译一段用符号代替字母的引文。我使用一些正则表达式来查找较长的单词,然后使用返回的单词来解决较小的单词。在拼图中,白色背景符号是元音(包括“y”),阴影背景符号是辅音。

我将在下面使用随机字母,其中粗体表示辅音,普通表示元音,斜体表示该字母是在说明中给出的。

QQ

上面的例子通过使用正则表达式被解读为“happy”(“e”已经在谜题中给出)

 egrep -i '^[bcdfghjklmnpqrstvwxz][aiouy][bcdfghjklmnpqrstvwxz]{2}[aiouy]$' words

有很多结果,但我觉得我可以通过将正则表达式逻辑地指定为来使正则表达式变得更好

  1. Char 1 是辅音
  2. Char 2 是元音,但不是“e”,因为它是在说明中给出的。
  3. 字符 3 和 4 是相同的辅音,但与字符 1 不同。
  4. 字符 5 是元音,但与字符 2 不同。

另一个例子是

e Dn

我在哪里使用了 grep 语句

egrep -i '^([aiouy])[bcdfghjklmnpqrstvwxz]e[bcdfghjklmnpqrstvwxz][aiouy][bcdfghjklmnpqrstvwxz]\1n$' words

从逻辑上将搜索定义为

  1. Char 1 是元音,并且是捕获组,因为相同的字符出现在单词的后面。
  2. Char 2 是辅音。
  3. 给出的字符 3 是“e”。
  4. Char 4 是辅音。
  5. Char 5 是元音。
  6. Char 6 是辅音。
  7. Char 7 与 Char 1 是相同的元音。
  8. 给出的字符 8 是“n”。

幸运的是,grep 语句返回了一个单词“American”(密文是电影台词)。我希望能够在正则表达式中指定 Char 4 是辅音,与 char 2 不同,char 5 是元音,与 char 1 不同,等等。

是否可以询问这种与正则表达式匹配的模式?我知道(x|y)声明字符可能是 ' 的语法X' 或者 'y',但我不知道语法(如果存在)来指定(!x) & y

答案1

您可以使用具有负先行功能的 Perl 正则表达式。

$ grep -Pi '^([aeiouy])([bcdfghjklmnpqrstvwxz])e(?!\2)([bcdfghjklmnpqrstvwxz])(?!\1)([aeiouy])(?!\2)(?!\3)([bcdfghjklmnpqrstvwxz])\1n$' /usr/share/dict/words
American
american
everymen

扩展:

$ perl -lnE '
    BEGIN { $vowel = qr/[aeiouy]/i; $consonant = qr/[bcdfghjklmnpqrstvwxz]/i }
    say if /^ ($vowel)                  # vowel
              ($consonant)              # consonant
              e                         # literal
              (?!\2)($consonant)        # different consonant
              (?!\1)($vowel)            # different vowel
              (?!\2)(?!\3)($consonant)  # 3rd different consonant
              \1                        # first vowel again
              n                         # literal
            $/xi
' /usr/share/dict/words
American
american
everymen

BOQQE 的例子是

grep -Pi '^([bcdfghjklmnpqrstvwxz])([aiouy])(?!\1)([bcdfghjklmnpqrstvwxz])\3(?!\2)([aiouy])$' /usr/share/dict/words

我的字典返回 779 个结果(444 个区分大小写)。

相关内容