regex - Bash 脚本 - 使用正则表达式分隔符拆分字符串

标签 regex string bash split sh

我想拆分字符串,例如“substring1 substring2 ONCE[0,10s] substring3”。预期结果应为(带分隔符“ONCE[0,10s]”):

substring1 substring2
substring3

问题是分隔符中的数字是可变的,例如'ONCE[0,1s]'或'ONCE[0,3m]'或'ONCE[0,10d]'等等。

我如何在 bash 脚本中执行此操作?有什么想法吗?

谢谢

最佳答案

OP 中提供的示例(以及@GlennJackman 和@devnull 提供的两个答案)假设实际问题可能是:

In bash, how do I replace the match for a regular expression in a string with a newline.

这实际上与“使用正则表达式拆分字符串”不同,除非您添加字符串不包含任何换行符的约束。即便如此,它实际上并没有“拆分”字符串;假定其他一些进程将使用换行符来拆分结果。

一旦问题被重新表述,解决方案就没有挑战性了。您可以使用任何支持正则表达式的工具,例如 sed:

sed 's/ *ONCE\[[^]]*] */\n/g' <<<"$variable"

(如果您只想替换第一个序列,请删除 g;您可能需要调整正则表达式,因为不太清楚所需的约束是什么。)

bash 本身不提供使用正则表达式的 replace all 原语,尽管它确实有“模式”,并且如果选项 extglob已设置(这是某些发行版的默认设置),模式足以表达模式,因此您可以使用:

echo "${variable//*( )ONCE\[*([^]])]*( )/$'\n'}"

同样,您可以通过将 // 更改为 / 来使替换只发生一次,并且您可能需要更改模式以满足您的精确需求。

对于“拆分”的某些定义,如何使用由正则表达式指定的定界符实际拆分 bash 变量的问题仍然悬而未决。一种可能的定义是“以字符串的各个部分作为参数调用一个函数”;这就是我们在这里使用的:

# Usage:
# call_with_split <pattern> <string> <cmd> <args>...
# Splits string according to regular expression pattern and then invokes
# cmd args string-pieces
call_with_split () { 
  if [[ $2 =~ ($1).* ]]; then
    call_with_split "$1" \
                    "${2:$((${#2} - ${#BASH_REMATCH[0]} + ${#BASH_REMATCH[1]}))}" \
                    "${@:3}" \
                    "${2:0:$((${#2} - ${#BASH_REMATCH[0]}))}"
  else
    "${@:3}" "$2"
  fi
}

例子:

$ var="substring1 substring2 ONCE[0,10s] substring3"
$ call_with_split " ONCE\[[^]]*] " "$var" printf "%s\n"
substring1 substring2
substring3

关于regex - Bash 脚本 - 使用正则表达式分隔符拆分字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23114583/

相关文章:

linux - 全明星节点编程

ASP.NET 密码强度正则表达式

javascript - 密码验证正则表达式

c - 字符串中的冗余字符,c

string - sprintf(将 int 转换为 char[])

arrays - 在 Bash 中获取关联数组( double )部分的长度

bash - Bash 中数组的双重插值

regex - 为 Perl 配置 Notepad++ "Function List"

java - 正则表达式 括号内的括号

python - 在 Python 中将 STDOUT 十六进制输出转换为字符串