迭代字符串数组,将正则表达式应用于 Korn Shell 中的每个元素

迭代字符串数组,将正则表达式应用于 Korn Shell 中的每个元素

我有一个名为的字符串数组,其中names包含名称和一些后续的垃圾数据。像这样

Jill Shortz, City Contractor, America
Bill Torts, Family Doctor, Canada
Will Courtz, Folk DJ, Bulgaria
Phil-Lip Warts, Juggler, India

我想通过names使用正则表达式仅提取前两个单词(^\w+-*( *\w+)*)并将它们重写回进行迭代names,以便它将包含

Jill Shortz
Bill Torts
Will Courtz
Phil-Lip Warts

这就是我尝试的方法,但我的 AIX 机器不喜欢-P在 Perl 模式下执行的参数

for((i=0;i<${#names[@]};++i)); do
        names[$i]=`grep -P '(^\w+-*( *\w+)*)' -o <<<"${names[i]}"`
done

答案1

我真的不认为正则表达式有什么用来完成这个任务,假设您只想删除第一个逗号之后的所有内容。

names=( "${names[@]%%,*}" )
printf '"%s"\n' "${names[@]}"

这是从每个数组元素中单独删除第一个逗号及其后面的所有内容(字面意思是“与通配模式匹配的最长后缀,*”)。然后将生成的修改名称列表重新分配给数组names(并用 打印printf)。

考虑到您将数组初始初始化为问题中的列表,该代码将生成

"Jill Shortz"
"Bill Torts"
"Will Courtz"
"Phil-Lip Warts"

(双引号是由printf格式字符串添加的)。

该代码适用于ksh93bashzshyash

答案2

我在 ksh 手册页中没有看到任何地方可以将字符串与正则表达式进行匹配,并使用捕获括号来提取子字符串(就像在 bash 中使用

[[ $str =~ ^([[:alnum:]]+([ -]+[[:alnum:]]+)+) ]] && echo "${BASH_REMATCH[1]}"

但是,您可以在 glob 模式中使用扩展正则表达式~(E:regex),因此您可以执行以下操作:

for n in "${names[@]}"; do
  # remove the pattern from the start of the string
  tmp=${n##~(E:\w+([ -]+\w+)*)}
  # and then remove what remained from the end of the string
  echo "[${n%$tmp}]"
done
[Jill Shortz]
[Bill Torts]
[Will Courtz]
[Phil-Lip Warts]

...以及最大程度的只写不可读性

for n in "${names[@]}"; do
  echo "${n%${n##~(E:\w+([ -]+\w+)*)}}"
done

相关内容