echo "223255/12345678 " | grep '[0-9a-zA-Z/\-\?:\(\)\.,"\+]{1,34}'
根据正则表达式,它可以包含0-9 a-z A-Z / - ? : ( ) . , " +
最多 34 个字符中的任何一个,且顺序不限。我对吗?
在这种情况下,为什么它不打印回显值?
答案1
您的代码存在几个问题:
- 在 内部
[...]
,唯一的特殊字符是-
and]
(尽管也[:
引入了字符类),转义它们的方法不是 with\
,而是 for-
使其成为列表中的第一个或最后一个字符 ([-...]
或[...-]
) 以及 for]
使其成为第一个字符([]...]
)。以上,表示到\-\
范围内的任何字符,即它包括,但不包括。所以你需要.\
\
\
-
[-0-9a-zA-Z/?:().,"+]
- 请注意,像
a-z
和这样的范围A-Z
取决于区域设置(like 可能包括 é、ŝ... 等内容),并且还可能包括多字节字符。如果您只想在这些范围内包含 ASCII 字符,则应将区域设置修复为 C:... | LC_ALL=C grep ...
{x,y}
是一个扩展的正则表达式运算符(由 所支持grep -E
)。相应的基本正则表达式(由 所支持grep
)运算符是\{x,y\}
。所以LC_ALL=C grep '[-0-9a-zA-Z/?:().,"+]\{1,34\}'
- 在 中
grep pattern
,grep
检查是否pattern
匹配任何地方里面每行输入。如果你想让它匹配全线,你需要-x
(对于精确的^
) 或使用和regexp 运算符将模式锚定在开头和结尾$
。grep -E 'x{1,34}'
与 相同grep x
,因为包含 1 到 34 的任意序列的行x
也包含 1x
,而包含 an 的行x
包含 1 的序列x
,因此与x{1,34}
正则表达式匹配。 - 假设您正在这样做
echo "$var" | grep the-pattern
,请注意它不可靠,因为echo
例如有些会变成-neen
空字符串,而另一些则会变成\n
换行符。另请注意,匹配的是输入的每一行,而不是整个输入,因此如果可能包含换行符,grep
您的检查可能无效。$var
最好是使用ksh93、zsh 或 bash 的操作expr
符来代替。[[ $var =~ pattern ]]
总而言之,如果你想检查它$var
是由 1 到 34 个 ASCII 字符组成,你应该这样写:
if LC_ALL=C expr "x$var" : 'x[-0-9a-zA-Z/?:().,"+]\{1,34\}$' > /dev/null; then
echo yes
else
echo no
fi
(expr
将模式隐式锚定到开头,就像有^
正则表达式运算符一样)
答案2
尝试使用egrep
或将-E
标志传递给grep
:
echo "223255/12345678 " | egrep '[0-9a-zA-Z/\-\?:\(\)\.,"\+]{1,34}'
或者
echo "223255/12345678 " | grep -E '[0-9a-zA-Z/\-\?:\(\)\.,"\+]{1,34}'
答案3
也许转义/
字符......有什么(\)
用?但似乎既然你在单引号内,你就不必转义你放入其中的所有内容。
我的调试建议是删除一些字符并查看您的模式有什么问题。