Bash Regex - 字符串不应以点开头和结尾

dep*_*par 3 bash shell-script regular-expression

我有一个脚本,它接受用户输入的字符串。我想检查字符串输入是否应该恰好有 2 个点。相关性仅与点有关。字符串不应以点开头和结尾。不应有连续的点。

这是我正在使用的模式:

^[^\.]*\.[^\.]*\.[^\.]*$
Run Code Online (Sandbox Code Playgroud)

这是我正在寻找的字符串

abc.def.xyz
Run Code Online (Sandbox Code Playgroud)

但在上面的模式中,如果点在前面或末尾,那么该字符串就会被选中 - 这是我不想要的。字符串中应该只有两个点。

不想要的:

.abc.xyz # no dot at the start   
abc.xyz. # no dot at the end   
abc.def.ced.xyz # only two dots not more than that
Run Code Online (Sandbox Code Playgroud)

我一开始就尝试使用(?!\.)for 点,但没有成功。

Sté*_*las 11

您并没有说明用户如何输入字符串,但请注意,如果它可能包含换行符,则无法使用grep过滤它们(除非您使用--null扩展名),因为grep一次只处理一行。另请注意,正则[^\.]表达式匹配除反斜杠和以外的字符,.并且许多正则表达式实现中的.正则表达式运算符(或[...])不会匹配在区域设置中不形成有效字符的字节。

在这里,要检查$string包含 2 个且仅 2 个点,但不在开头或结尾且不彼此相邻,您可以使用标准sh

case $string in
  (*.*.*.* | .* | *. | *..* ) echo not OK;;
  (*.*.*) echo OK;;
  (*) echo not OK;;
esac
Run Code Online (Sandbox Code Playgroud)

或者使用 ksh glob,可以通过执行以下操作在 bash shell 中使用 ksh glob 的子集shopt -s extglob

case $string in
  ( +([!.]).+([!.]).+([!.]) ) echo OK;;
  (*) echo not OK;;
esac
Run Code Online (Sandbox Code Playgroud)

bash还可以=~在其[[...]]ksh 样式构造中与运算符进行扩展正则表达式匹配,但同样,您需要将语言环境修复为 C:

regex_match_in_C_locale() {
  local LC_ALL=C
  [[ $1 =~ $2 ]]
}

if regex_match_in_C_locale "$string" '^[^.]+\.[^.]+\.[^.]+$'; then
  echo OK
else
  echo not OK
fi
Run Code Online (Sandbox Code Playgroud)

POSIXly,您可以使用该实用程序进行基本的正则表达式匹配expr

if
  LC_ALL=C expr "x$string" : 'x[^.]\{1,\}\.[^.]\{1,\}\.[^.]\{1,\}$' > /dev/null
then
  echo OK
else
  echo not OK
fi
Run Code Online (Sandbox Code Playgroud)

或与awk实用程序匹配的扩展正则表达式:

regex_match_in_C_locale() {
  LC_ALL=C awk -- 'BEGIN {exit(ARGV[1] !~ ARGV[2])}' "$@"
}
if regex_match_in_C_locale "$string" '^[^.]+\.[^.]+\.[^.]+$'; then
  echo OK
else
  echo not OK
fi
Run Code Online (Sandbox Code Playgroud)


sch*_*ity 5

我认为您正在寻找这个正则表达式^[^.]\+\.[^.]\+\.[^.]\+$,在这个例子中我们将使用grep

括号内的字符按字面意思处理(除了-),因此不需要转义点。

$ echo ".a.b.c." | grep  "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo ".a.b.c"  | grep  "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo "a.b.c."  | grep  "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo "a..c"    | grep  "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo "a.b.c"   | grep  "^[^.]\+\.[^.]\+\.[^.]\+$"
a.b.c
Run Code Online (Sandbox Code Playgroud)

正则表达式说

  • 该字符串必须以一个或多个非点字符开头,后跟一个点^[^.]\+\.,再后跟一个或多个非点字符[^.]\+\.,再后跟一个或多个非点字符,[^.]\+$直到行尾。

  • `\+` 是 GNU 扩展。标准等效项是 `\{1,\}` 或使用 `grep -E` 来扩展正则表达式,然后使用 `+`。 (3认同)