使用GREP和Regex查找文本中重复的位置模式



我正试图解决一个密码难题,其中所有字符都被非字母数字符号取代。

我正在尝试使用grep和字典来查找可能与密码中的模式匹配的单词。

例如,假设我的谜题中有以下单词:

@&!*&;?

我想使用grep在字典中搜索在第2和第5位包含相同字母的7个字母的单词。

我认为grep必须能够做到这一点,但我还没有弄清楚如何做到。

在字典中搜索在第2和第5位包含相同字母的7个字母的单词,仅

使用GNU grep和反向引用:

grep -E '^.(.)..1..$' file

使用此单词表输出(前15行(:

空运航空公司Airsick播放时间苜蓿碱性天线反义词Badland行李绷带bandaid减价品混蛋相信

参见:man grep和堆栈溢出正则表达式常见问题

我认为建议一些可以用于针对任意模式测试单词的代码可能会很有意思。下面的代码是用Ruby编写的,但我已经把它做得很简单,并对它进行了大量注释,所以应该能够很容易地将它转换为大多数通用语言。

我将首先定义一个助手方法,该方法将单词模式转换为哈希,从而可以轻松确定给定单词是否与模式匹配。

def repeats_map(pattern)
# create an empty hash that maps the first appearance of a char in
# pattern to its index in the string
chars_to_idx = {}              
# create an empty hash that maps, for each char that is a repeat, its
# index i in pattern to the index of the first occurrence of the char
# in pattern
repeats = {}
# loop through indices of chars in pattern
(0..pattern.size-1).each do |i|
# extract char at offset i in pattern
c = pattern[i]
# see if c has already been seen
if chars_to_idx.key?(c)
# specify that char at offset i equals at offset chars_to_idx[c]
repeats[i] = chars_to_idx[c]
else
# add c=>i key-value pair to # add c=>i key-value pair to h
chars_to_idx[c] = i
end
end
# return repeats
repeats
end

通过计算几个例子,这种方法应该会变得更加清晰。

repeats_map("@&!*&;?")      #=> {4=>1}
repeats_map("@&!*&;?&")     #=> {4=>1, 7=>1}
repeats_map("@&!*&;;&")     #=> {4=>1, 6=>5, 7=>1} 
repeats_map("@&!*&@;?!&!*") #=> {4=>1, 5=>0, 8=>2, 9=>1, 10=>2, 11=>3}

如果应用第一个模式("@&!*&;?"(,则如果索引4处的字等于索引1处的字,则(长度为"@&!*&;?".size #=> 7的(字与该模式匹配。例如,"凉鞋"匹配,而"日晷"则不匹配。对于第二种模式,索引47处的单词字符必须都等于索引1处的字符。

我们现在可以编写一个方法来确定给定的单词是否与给定的模式匹配。

def word_matches?(word, pattern)
return false if word.size != pattern.size
# obtain repeats hash from pattern
repeats = repeats_map(pattern)
# convert all chars of word to lower case
w = word.downcase
# loop over each character index in word to determine if a condition
# is true for all indices     
(0..w.size-1).all? do |i|
# return true for index i if repeats does not have a key i or if
# does have a key i and the char at index i of word equals the
# char at index repeats[i] of word; else return false
repeats.key?(i) == false || w[i] == w[repeats[i]]
end
end

假设

pattern = "@&@*&?"

因此

pattern.size                       #=> 6
repeats_map(pattern)               #=> {2=>0, 4=>1}

word_matches?("avarve",  pattern)  #=> true 
word_matches?("dodroe",  pattern)  #=> true 
word_matches?("avarves", pattern)  #=> false 
word_matches?("avarv",   pattern)  #=> false 
word_matches?("avarwe",  pattern)  #=> false 
word_matches?("averve",  pattern)  #=> false

有些读者可能不熟悉"avarve"one_answers"dodroe"这两个词,但我在拼字游戏中使用过这两个单词,没有受到质疑,所以我相信它们是真实的单词。

最新更新