【问题标题】:String validation using regular expressions in bash [duplicate]在bash中使用正则表达式进行字符串验证[重复]
【发布时间】:2018-11-25 10:16:49
【问题描述】:

我一直很难将正则表达式锁定在 bash 中。我正在编写一个脚本,该脚本旨在读取包含名称列表的文件。我打算验证每个名称。

文件是这样的:

John, Smith
Jane, Doe S.
stan, smith

有效名称的格式如下:

  • 必须用逗号分隔姓氏和名字。
  • 名字必须以大写字母开头,后跟小写字母(姓氏也是如此)。
  • 中间名首字母是可选的,但如果确实存在,则它必须是大写字母并且后面必须跟一个句点 (.)。

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

我尝试过诸如

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

至少验证姓氏。但这显然行不通。

【问题讨论】:

  • 没错! @Aaron 但它说所有这些都是无效的
  • 嗯,实际上^ 似乎没有被理解为元字符引用模式时[[ "foo" =~ "^foo" ]] && echo ok 失败,而[[ "foo" =~ ^foo ]] && echo ok 成功
  • @Aaron 你是对的,如果模式被引用,它被解释为字符串,而不是模式。
  • @Aaron 删除引号确实有点帮助。现在我看到了一条可以遵循的道路。谢谢

标签: regex string bash awk


【解决方案1】:

最好在单独的变量中声明模式,然后只使用该变量,因为这样可以避免引用问题,并且与所有支持正则表达式的 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。

【讨论】:

  • 像魅力一样工作。确实需要对正则表达式进行一些研究。你能解释一下表达式的最后一部分是什么意思吗? “+( [[:upper:]].)?”
  • @DuckDodgers + 是它前面的[[:lower:]] 的一部分,意思是“其中一个或多个”。然后,( [[:upper:]\.)?(我刚才插入了反斜杠!)是“一个空格,一个大写字符,一个句点”(转义为\.,因为.是“任何字符”),而?在end 表示“这些中的零个或其中之一”,即可选。
  • 非常感谢。我很感激
【解决方案2】:

最好使用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]\.)?$/:检查名字是否以大写字母开头,后跟小写字母。中间名也有一个可选匹配,它只是一个大写字母后跟点。

【讨论】:

  • 这很好用。我将在 awk 上阅读更多内容。谢谢
猜你喜欢
  • 1970-01-01
  • 2020-09-16
  • 2014-02-08
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
相关资源
最近更新 更多