【问题标题】:ZSH regex pattern matches in tester but not in useZSH 正则表达式模式在测试器中匹配但未使用
【发布时间】:2022-06-26 14:12:41
【问题描述】:

在 zsh shell 脚本 (sdk.sh) 中,我有一个可以根据用户偏好输入四种方式的命令。脚本应该找出输入的模式,然后采取相应的行动。

我的正则表达式在 https://www.regextester.com/107384 中有效,但在脚本中无效,我不知道为什么。

执行时输入值:./sdk.sh sitename.stage PSD-00000

正则表达式

需要多个模式,以便无论输入如何,输出(将是一个 shell 命令)都将被构造为sitename.stage PSD-12345

pattern1="^([A-z0-9])+\.stage+\s+(PSD-)+[0-9]+$"    ## ex: sitename.stage PSD-00000
pattern2="^([A-z0-9])+\s+(PSD-)+[0-9]+$"            ## ex: sitename PSD-00000
pattern3="^([A-z0-9])+\s+[0-9]+$"                   ## ex: sitename 00000
pattern4="^([A-z0-9])+\.stage+\s+[0-9]+$"           ## ex: sitename.stage 00000

条件测试

这些正则表达式在 https://www.regextester.com/107384 处找到匹配项,无论是否包含开头 ^ 和结尾 $ 字符,但它们在此处找不到匹配项。

# Check that input value exists and which pattern it matches

if [[ -n "$value" ]]; then
  echo "0. Inputted value: ${value}"

  if [[ "$value" =~ $pattern1 ]];  ## ex: sitename.stage PSD-00000
  then
    sitePhase=$value
    echo "1. value = $value | sitePhase = $sitePhase"

  elif [[ "$value" =~ $pattern2 ]];  ## ex: sitename PSD-00000
  then
    sitePhase="$value (add .stage to first input)"
    echo "2. value = $value | sitePhase = $sitePhase"

  elif [[ "$value" =~ $pattern3 ]]; ## ex: sitename 00000
  then
    sitePhase="$value (add .stage to first input, PSD- to second input"
    echo "3.  value = $value | sitePhase = $sitePhase"

  elif [[ "$value" =~ $fullPattern4 ]]; ## ex: sitename.stage 00000
  then
    echo "4.  value = $value | sitePhase = $sitePhase"

  else
    echo "No matches"
  fi
fi

输出

0. Inputted value: equinix.stage PSD-00000
No matches

表明$value 具有价值,因此应该能够被测试,并且无论出于何种原因,在测试器上匹配的正则表达式在脚本中不匹配。

问题

  1. 我错过了什么?
  2. 在此中包含开头^ 和结尾$ 字符是否重要? 案子?为什么/不?
  3. zsh 正则表达式与 bash 正则表达式不同吗?如果是这样我真的找不到 任何容易找到的在线文档。

【问题讨论】:

  • 您是否有意使用多个正则表达式模式?单个^[[:alnum:]]+(\.stage)?([[:space:]](PSD-)?)?[0-9]+$ 怎么样?
  • 是的,我愿意,因为每一个都需要单独处理,才能根据输入得到正确的最终输出。我会记下这一点。谢谢你:)
  • 实际上,使用这个单一的正则表达式,您可以分析捕获的组并采取相应的行动。
  • 我认为 \s 在您的模式中无法识别。尝试使用[[:space:]] 而不是\s
  • 正则表达式有效,谢谢,但我如何在 if 语句中调用它,例如,if [ ".space" = $match[1] ] 是由于数组大括号的语法错误。找不到这方面的文档。

标签: regex bash zsh


【解决方案1】:

请注意,仅匹配字母,[A-z] 不是正确的模式,它应该是 [A-Za-z],但在这里,由于您需要匹配字母数字,[[:alnum:]] 似乎是更好的对应物。

在您的正则表达式中,\s 不会被解析为空白模式,而仅仅是s 字母模式。

我建议使用单个正则表达式来捕获匹配各种输入字符串的组。然后,您可以检查特定组是否参加了比赛,并执行相应的逻辑。

这是一个例子:

setopt BASH_REMATCH
value='sitename.stage PSD-00000'
pattern='^[[:alnum:]]+(\.stage)?([[:space:]](PSD-)?)?[0-9]+$'
if [[ -n "$value" ]]; then
  echo "0. Inputted value: ${value}"
 if [[ "$value" =~ $pattern ]]; then  ## ex: sitename.stage PSD-00000
   if [[ -n "${BASH_REMATCH[1]}" &&  -n "${BASH_REMATCH[2]}" &&  -n "${BASH_REMATCH[3]}" ]]; then
    sitePhase=$value
    echo "1. value = $value | sitePhase = $sitePhase"
   elif [[ -n "${BASH_REMATCH[2]}" && -n "${BASH_REMATCH[3]}" ]]; then  ## ex: sitename PSD-00000
    sitePhase="$value (add .stage to first input)"
    echo "2. value = $value | sitePhase = $sitePhase"
   elif [[ -z "${BASH_REMATCH[2]}" && -z "${BASH_REMATCH[2]}" && -z "${BASH_REMATCH[3]}" ]]; then ## ex: sitename 00000
    sitePhase="$value (add .stage to first input, PSD- to second input"
    echo "3.  value = $value | sitePhase = $sitePhase"
   elif [[ -n "${BASH_REMATCH[1]}" ]]; then ## ex: sitename.stage 00000
    echo "4.  value = $value | sitePhase = $sitePhase"
   fi
  else
    echo "No matches"
  fi
fi

查看online demo 打印预期

0. Inputted value: sitename.stage PSD-00000
1. value = sitename.stage PSD-00000 | sitePhase = sitename.stage PSD-00000

详情

  • ^ - 字符串开头
  • [[:alnum:]]+ - 一个或多个字母数字字符
  • (\.stage)? - 第 1 组(可选):.stage 字符串
  • ([[:space:]](PSD-)?)? - 第 2 组(可选):一个空格,然后是一个可选的第 3 组,捕获 PSD- 字符串
  • [0-9]+ - 一位或多位数字
  • $ - 字符串结束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    相关资源
    最近更新 更多