匹配至少一个小写字母和至少一个大写字母

Matching at least one lower case letter AND at least one upper case letter

我正在尝试提取具有一个约束的单词 [a-zA-Z]+:一个单词必须包含至少一个小写字母和至少一个大写字母(在单词中的任何位置)。示例:如果输入是 hello 123 worLD,唯一的匹配应该是 worLD.

我试过像这样使用积极的前瞻:

echo "hello 123 worLD" | grep -oP "(?=.*[a-z])(?=.*[A-Z])[a-zA-Z]+"
hello

这是不正确的:唯一匹配的是 hello 而不是 worLD。然后我试了这个:

echo "hello 123 worLD" | grep -oP "\K((?=.*[a-z])(?=.*[A-Z])[a-zA-Z]+)"
hello
worLD

这仍然不正确:hello 不应匹配。

前瞻中的 .* 不仅检查相邻单词中的字母,而且检查字符串后面的字母。使用 [a-zA-Z]*:

echo "hello 123 worLD" | grep -oP "\b(?=[A-Za-z]*[a-z])(?=[A-Za-z]*[A-Z])[a-zA-Z]+"

demo online

我还在开头添加了一个词边界 \b 以便仅在词边界之后执行前瞻检查。

答案:

echo "hello 123 worLD" | grep -oP "\b(?=[A-Z]+[a-z]|[a-z]+[A-Z])[a-zA-Z]*"

演示:https://ideone.com/HjLH5o

解释:

首先检查单词是否以一个或多个大写字母开头,后跟一个小写字母,或者反之亦然,后跟任意数量的大小写字母,顺序任意。

性能:

This solution takes 31 steps to reach the match on the provided test string, while the accepted solution 需要 47 步。