我有一个名为的字符串数组,其中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
格式字符串添加的)。
该代码适用于ksh93
、bash
、zsh
和yash
。
答案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