鉴于对规则的澄清,并鉴于环境是 linux 并且我们正在使用 grep,这有助于提供更好的答案!:)
我现在解决这个问题的方法不是使用单个正则表达式。规则过于复杂,无法用一个简单的正则表达式优雅地解决。但是,这是一个很好的起点(假设源文件是 pass.txt):
grep -E -o '[a-zA-Z0-9_$%*@#]{10,}' ./pass.txt
-E 表示未启动的表示扩展的正则表达式,这本质上意味着更多的正则表达式功能,例如 {} 不再需要转义,因此无需所有额外的斜杠就更容易阅读。
-o 只返回文件的匹配部分,而不是返回整行。
请注意单引号的使用,这很有帮助,因为$
双引号中的字符将被解释为变量名的开头。单引号表示它被视为文字。
上述正则表达式的缺陷是您将匹配许多误报,例如以下示例中的最后三个:
Password@1234
sffa##1233P
Moose**F00!d
Dollar$$01234
Dollar$$NoNum
NothingSpecial123
123#@#@123456
whereDollar$$NoNum
没有数字,NothingSpecial123
没有特殊字符,123#@#@123456
也没有字母字符。
但是,我们可以通过使用竖线 ( ) 字符将许多 grep 命令链接在一起来过滤掉这些误报|
,并过滤掉不具有必需属性的项目。
例如,要过滤掉不包含字母字符的项目,我们可以使用以下内容:
grep -E -o '[a-zA-Z0-9_$%*@#]{10,}' ./pass.txt | grep -E -v '^[^a-zA-Z]+$'
注意到我们在第一个 grep 中使用了 -o,现在我们可以通过以 开头和结尾来明确匹配密码的开头^
和结尾$
。匹配本身是一个反转字符类 ( [^.....]
),它将匹配方括号中未指定的任何文本。例如,[^a]
将匹配任何不是 NOT 的字符,例如a
匹配b
。在我们的示例中,我们匹配的不是字母字符。因为我们也在匹配密码的开头和结尾,如果我们匹配,那么我们知道我们这里有一个密码,它完全由非字母的文本组成,这违反了规则#4,因为它应该包含一个字母特点。
然而,这与我们想要的相反 - 这将找到没有字母字符的匹配项。Grep 相当有用地允许我们使用 -v 反转输出,这正是我们想要的。因此,上面的输出将过滤掉不包含字母字符的匹配项。
将相同的原则应用于其他规则,我们得到以下最终 grep 命令:
grep -E -o '[a-zA-Z0-9_$%*@#]{10,}' ./pass.txt | grep -E -v '^[^a-zA-Z]+$' | grep -E -v '^[^0-9]+$' | grep -E -v '^[^$%*@#]+$'
前一个 grep 命令的过滤输出馈送到下一个过滤器,到最后,我们已经删除了所有的误报。