你的尝试

你的尝试

我想提示用户输入一个URL ,但它只能包含A-Z,,,,,,,,,,,,,,,和。a-z0-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

相关内容