在bash中使用正则表达式进行字符串验证

时间:2018-06-15 14:38:23

标签: regex string bash awk

我很难将正则表达式锁定在bash中。我正在编写一个脚本,用于读取包含名称列表的文件。我的意思是验证每个名字。

文件是这样的:

John, Smith
Jane, Doe S.
stan, smith

有效名称的格式如下:

  • 必须以逗号分隔的姓氏和名字。
  • 名字必须以大写字母开头,后跟小写字母(姓氏相同)。
  • 中间名首字母是可选的,但如果确实存在,则必须是大写字母,后面必须跟一段句子.

这意味着只有文件中的前两个名称有效。 我已经拖了一段时间了。有人可以帮忙吗?

我尝试过像

这样的表达式
if [[ "${name}" =~ "^[A-Z]{1}[a-z]" ]]

至少验证姓氏。但它显然不起作用。

2 个答案:

答案 0 :(得分:2)

优良作法是在单独的变量中声明模式,然后只使用该变量,因为这可以避免引用问题,并且与支持正则表达式的所有Bash版本兼容 1

re='^[[:upper:]][[:lower:]]+, [[:upper:]][[:lower:]]+( [[:upper:]]\.)?$'
while read -r name; do
    [[ $name =~ $re ]] && echo "$name matches"
done < infile

1 正则表达式解析在Bash版本3.1和3.2之间发生了变化,请参阅Chet's FAQ,E14。

答案 1 :(得分:1)

最好使用awk代替BASH

awk -F '[[:blank:]]*,[[:blank:]]*' '
$1 ~ /^[A-Z][a-z]*$/ && $2 ~ /^[A-Z][a-z]*( [A-Z]\.)?$/' file

John, Smith
Jane, Doe S.

<强>详细信息:

  • -F '[[:blank:]]*,[[:blank:]]*'将每一行拆分为字段,分隔符为逗号,两边都是可选空格。
  • $1 ~ /^[A-Z][a-z]*$/:检查名字是否以大写字母开头,后跟小写字母。
  • $2 ~ /^[A-Z][a-z]*( [A-Z]\.)?$/:检查名字是否以大写字母开头,后跟小写字母。对于中间名称也有可选匹配,这只是一个大写字母后跟点。