Bash 正则表达式捕获组

mha*_*ken 4 regex bash grep pcre

我有一个这种格式的字符串:

"Mike H<michael.haken@email1.com>" michael.haken@email2.com "Mike H<hakenmt@email1.com>"
Run Code Online (Sandbox Code Playgroud)

如果我在 JS、C# 等中编写一个普通的正则表达式,我会这样做

(?:"(.+?)"|'(.+?)'|(\S+))
Run Code Online (Sandbox Code Playgroud)

并迭代匹配组以获取每个字符串,理想情况下没有引号。我最终想将每个值添加到数组中,因此在示例中,我最终会在数组中包含 3 个项目,如下所示:

Mike H<michael.haken@email1.com>
michael.haken@email2.com 
Mike H<hakenmt@email1.com>
Run Code Online (Sandbox Code Playgroud)

我不知道如何使用greporsed或 bash 正则表达式复制此功能。我尝试过一些类似的事情

echo "$email" | grep -oP "\"\K(.+?)(?=\")|'\K(.+?)(?=')|(\S+)"
Run Code Online (Sandbox Code Playgroud)

问题在于,虽然它有点模仿捕获组的功能,但它并不真正适用于倍数,所以我得到了类似的捕获

"Mike
H<michael.haken@email1.com>"
 michael.haken@email2.com 
Run Code Online (Sandbox Code Playgroud)

如果我删除前瞻/后视逻辑,我至少会得到 3 个字符串,但第一个和最后一个仍然用引号括起来。在这种方法中,我将输出通过管道传输到,read以便我可以将每个字符串单独添加到数组中,但我对其他选项持开放态度。

编辑:

我认为我的输入示例可能令人困惑,这只是一个可能的输入。实际输入可以是任意数量的任意顺序的双引号、单引号或非引号(无空格)字符串。我提供的 Javascript/C# 正则表达式是我试图实现的真实行为。

daw*_*awg 5

你可以使用 Perl:

$ email='"Mike H<michael.haken@email1.com>" michael.haken@email2.com "Mike H<hakenmt@email1.com>"'
$ echo "$email" | perl -lane 'while (/"([^"]+)"|(\S+)/g) {print $1 ? $1 : $2}' 
Mike H<michael.haken@email1.com>
michael.haken@email2.com
Mike H<hakenmt@email1.com>
Run Code Online (Sandbox Code Playgroud)

或者在纯 Bash 中,它有点罗嗦:

re='\"([^\"]+)\"[[:space:]]*|([^[:space:]]+)[[:space:]]*'
while [[ $email =~ $re ]]; do
    echo ${BASH_REMATCH[1]}${BASH_REMATCH[2]}
    i=${#BASH_REMATCH}
    email=${email:i}
done 
# same output
Run Code Online (Sandbox Code Playgroud)


mha*_*ken 0

我能够做的事情有效,但没有我想要的代码那么简洁:

arr=()
while read line; do
  line="${line//\"/}"
  arr+=("${line//\'/}")
done < <(echo $email | grep -oP "\"(.+?)\"|'(.+?)'|(\S+)")
Run Code Online (Sandbox Code Playgroud)

这给了我一个捕获组的数组,并以任何顺序处理输入,用双引号或单引号括起来,或者如果没有空格则根本不用括起来。它还提供了数组中没有引号的元素。感谢所有的建议。