我想提示用户输入一个URL ,但它只能包含A-Z
,,,,,,,,,,,,,,,和。a-z
0-9
&
.
/
=
_
-
:
?
因此,例如:
Enter URL:
$ http://youtube.com/watch?v=1234df_AQ-x
That URL is allowed.
Enter URL:
$ https://unix.stackexchange.com/$FAKEurl%
答案1
你很接近。
您想要检查 URL 是否至少包含一个不允许的字符(然后将其报告为无效),而不是至少包含一个允许的字符。
!
您可以使用(^
也适用于bash
和其他一些 shell)来否定括号表达式中的字符集。
无论如何,您单独显式列出字符是正确的,使用诸如a-z
, A-Z
,之类的范围0-9
仅适用于(仅匹配您列出的 26+26+10 个字符)C语言环境在其他语言环境中,它们可以匹配数千个其他字符,甚至可以匹配由多个字符组成的排序元素(例如在A
和之间排序的元素)。Z
É
A-Z
case $URL in
("" | *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_/\&?:.=-]*)
echo >&2 "That URL is NOT allowed.";;
(*)
echo "That URL is allowed.";;
esac
答案2
你的尝试
您的尝试可能无法按预期工作,因为它认为所有包含至少一个允许字符的 URL 都是允许的。正式而言,您将 URL 与
<anything><allowed_character><anything>
如果不匹配,您将拒绝该 URL。
这可能有帮助
如果你if ... else ... fi
用
if [[ "${URL}" =~ [^A-Za-z0-9\&./=_:?-] ]]; then
echo "That URL is NOT allowed."
else
echo "That URL is allowed."
fi
它可能会做你想做的事。
这里,二元运算符=~
用于查找 中正则表达式的匹配[^A-Za-z0-9\&\./=_-:\?]
项"${URL}"
。该运算符不要求整个字符串"${URL}"
与正则表达式匹配,任何匹配的子字符串都可以。可以为 URL 中不允许的任何字符找到此类匹配。 “not”来自^
字符集定义中的前导插入符号 ( )。请注意,!
条件表达式中不再有否定。
如果"${URL}"
包含禁止字符,则正则表达式匹配并且复合命令的[[...]]
计算结果为 true(零退出状态)。
答案3
您当前的逻辑是错误的,仅当输入 URL 中的每个字符都存在于允许的字符集之外时,它才会返回 true。
尝试一些类似的事情
if [[ "${URL}" = *[!A-Za-z0-9\&./=_:?-]* ]]
then
echo "That URL is NOT allowed."
else
echo "That URL is allowed"
fi
由于字符范围内的否定 (!),此检查旨在当输入 URL 包含允许的字符集之外的一个或多个字符时返回 true
答案4
紧凑型解决方案
如果您喜欢紧凑的解决方案,可以使用以下解决方案:
[ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ] && echo No || echo Yes
解释
该解决方案使用形式的参数扩展,${<variable>//<pattern>}
这是更一般形式的特例
${<variable>//<pattern>/<replace>}
shell 将其扩展为 的值<variable>
,其中 的所有匹配项<pattern>
都被替换为<replace>
。在我们的例子中,<replace>
是空的,也允许省略 后面的斜杠<pattern>
。
结果,"${URL//[A-Za-z0-9\&.\/=_:?-]}"
将扩展为 URL,并删除所有允许的字符。如果没有残留,即允许该 URL,则[ ... ]
实际上是[ ]
,这会产生 false(退出状态 0)。如果还有剩余字符,则它们被禁止,并且[ ... ]
具有形式[ <nes> ]
,其中<nes>
是一个非空字符串,其结果为 true(退出状态 1)。
&&
整个命令是由控制运算符(and) 和(or)分隔的三个命令的列表||
,这些命令是左关联的。因此,子列表
[ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ] && echo No
首先被评估。在那里,&&
当且仅当第一个操作数的计算结果为 true(零退出状态)时,才会计算 的第二个操作数。如果 URL 包含禁用字符,就会出现这种情况。因此,echo
在这种情况下给出了正确的答案“否”,并且该子列表的退出状态来自此echo
命令:0(真)。
相反,如果允许该 URL,则该子列表的退出状态来自[ ... ]
:1(假)。
现在列出列表的其余部分:
<sub-list> || echo Yes
||
当且仅当其第一个操作数为 false(退出状态不同于零)时,该运算符才执行最后一个命令。因此,只有当<sub-list>
为 false 时,即对于允许的 URL,我们才会得到“是” ,因为它应该是这样。
如果结构
当然,您[ ... ]
也可以在if
结构中使用上述命令。在大多数情况下,这将产生更好的可读代码:
if [ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ]; then
echo "That URL is NOT allowed."
else
echo "That URL is allowed."
fi