我想制作一个 bash 脚本,它应该决定给定的字符串,如果它们是否满足该术语。
这些条款是:
- 字符串的前 3 个字符必须是"le-"
- 在连字符之间,任何排列方式中都可以有任意数量的辅音,只有一个"e",它不能包含任何元音。
- 连字符之间一定有什么东西
- 字符串不得以连字符结尾
我做了这个脚本:
#!/bin/bash
# Testing regex
while read -r line; do
if [[ $line =~ ^le((-[^aeiouW]*e+[^aeiouW]*)+)$ ]]
then
printf """$line""ttt-> Truen";
else
printf """$line""ttt-> Falsen";
fi
done < <(cat "$@")
它做得很好,除了一件事:无论有多少个连字符彼此相邻,它都表示为真。例如:它对这个字符串"le--le"说真
我在网站上尝试了这个正则表达式(像这样),它们在没有此故障的情况下工作。我能想到的网页和linux bash之间一定有什么区别。(我在网页上只能看到它运行PHP)
你有什么想法吗,我怎样才能让它工作?
感谢您的回答!
sweaver2112 正确地指出W
给您带来了问题,但未能提供 bash 测试正则表达式的工作示例,该示例可以按照您的要求进行操作(至少,我无法让它工作)。
这似乎做到了(改编劳雷尔的辅音正则表达式):
[[ "$line" =~ ^le(-[b-df-hj-np-tv-z]*e[b-df-hj-np-tv-z]*)+$ ]]
它匹配(例如):
le-e
le-e-le
le-e-e-e-e-e
更一般地说:
le-([[:consonant:]]*e[[:consonant:]]*)+
并且不匹配(例如):
le-
le--le
le-lea-le
此外,您可以通过这种方式更干净地编写它:
c='[b-df-hj-np-tv-z]'
[[ "$line" =~ ^le(-$c*e$c*)+$ ]]
你的正则表达式至少有一个问题:[^aeiouW]
- 一个否定的"non-word",意思是"单词" - 它匹配任何字母,包括辅音。字符类是包容性的,而不是排他性的。我们最好只列出所有辅音(对于您的情况,我们还会在集合中添加"e"和"-")。
所以试试这个:(编辑:使用@Laurel更简洁的字符类)
`(?=^le-)(?!.*--)(?!.*-[^-]*e[^-]*e[^-]*-)[b-hj-np-tv-z-]*[^-]$`
-
(?=^le-)
以"le-"开头 -
(?!.*--)
不允许使用双破折号 -
(?!.*-[^-]*e[^-]*e[^-]*-)
在破折号之间看不到两个 e -
[b-hj-np-tv-z-]*
- 使用辅音、e 和破折号(与[bcdfghjklmnpqrstlvwze-]
相同) -
[^-]$
最后一个字符必须是非短划线