POSIX 正则表达式匹配字符串第一次出现的位置

POSIX 正则表达式匹配字符串第一次出现的位置

我有 bash 脚本,我只想支持长选项(“--option”)。 --option 可以选择包含一个或多个参数。直到但不包括第一个“--”或命令行字符串末尾的所有单词(任何由空格分隔的内容)都被视为“--option-arguments”。结果中的尾随空格是可以的。由于每个可能的选项都会被其他函数调用,因此需要最大的性能。因此,尽量避免 bash 循环和外部命令。

与“第一次出现”问题斗争了很多小时,直到我发现这个答案这提醒我 POSIX(以及 bash)不支持非贪婪/惰性正则表达式运算符。

该怎么办?

答案1

您无法按照您想要的方式使用正则表达式解析选项,因为选项不是以字符串形式传递,而是以列表字符串。myscript --option foo bar -- quxmyscript, --option, foo, bar,--qux作为单独的参数,它们都不包含空格。

循环是 bash 中的方法。

case "$1" in
  --option1)
    shift
    while [[ $# -ne 0 && "$1" != "--" ]]; do
      option1_args+=("$1")
      shift
    done
    (($# == 0)) || shift
done

如果性能是一个大问题,那么您就不应该使用 bash。尝试使用 ksh — 它是免费的,几乎可以在任何地方使用,即使它没有默认安装,而且它通常比 bash 快得多。如果这仍然太慢,您需要一种更高级的编程语言,例如 Perl、Python 或 Ruby。

答案2

发现这个相当简单的解决方案......

function optionArg () {
  local _find="$1"; shift 1
  local _optarg=""
  local _reBeg=""
  #
  _reBeg="${_find}"'[= ]+(.*?)( --)?'
  ### no regex nongreedy operator support in POSIX
  ### will have to just truncate after first match
  #
  if [[ "$*" =~ $_reBeg ]]
  then
    _optarg="${BASH_REMATCH[1]}"
    ### all arguments following --option[= ]
    #
    _optarg="${_optarg%%--*}"
    ### limit to just arguments up to next --option (no lazy support in POSIX)
    #
    return 0
  else
    return 1
  fi

给定一个带有选项的脚本或函数调用,后跟其他选项,例如......

otherfunction --option1 arg1 arg2 --option2 -- file1 /home/me/file2

对于 otherfunction() 接受的每个选项, optionArg() 将被调用,就像......

_optarg1="$(optionArg --option1 "$@")"
_optarg2="$(optionArg --option2 "$@")"
_optarg3="$(optionArg --        "$@")"

结果将是...

_optarg1="arg1 arg2 "
_optarg2=""
_optarg3="file1 /home/me/file2"

相关内容