我有一个这样的字符串:
a1="a,b,c,(d,e),(f,g)";
如何获得像这样的数组
arr=["a","b","c","d,e","f,g"];
我想用其他字符替换括号之间的逗号并在转换为数组后将其还原
但我不知道如何只替换括号之间的逗号;如何才能做到这一点?
sed 's/,/\",\"/g;s/(\(.\)\"/\1/g;s/\"\(.\))/\1/g;s/^\w\+=\"/arr=[\"/;s/;/];/'
写一个解析器!:D
我不知道如何在 bash 中执行此操作,但我可以向您展示如何在 PHP 中执行此操作(应该可以转换为其他语言)。
$str = "a,b,c,(d,e),(f,g)";
$out = array();
$current_token = "";
$open_brackets = 0;
$length = strlen($str)
for ($i = 0; $i < $length; $i += 1) {
$chr = $str[$i];
if ($chr === "(") {
$open_brackets += 1;
} else if ($chr === ")") {
$open_brackets -= 1;
} else if ($open_brackets === 0 && $chr === ",") {
$out[] = $current_token; // push token value to out
$current_token = "";
} else {
$current_token .= $chr;
}
}
if (strlen($current_token) > 0) {
$out[] = $current_token; // dont forget the last one
}
var_dump($out); // ["a","b","c","d,e","f,g"]
未经测试,但这是大纲。跟踪括号的数量,只有当括号匹配时,才应将,
其解释为分隔符。
尝试使用正则表达式解析字符串的bash脚本。这对我来说很尴尬,但似乎有效:
#!/usr/bin/env bash
unset arr
a1="a,b,c,xxx(d,e),sdf(f,g)"
## The regular expression does an alternation between
## a pair of parens followed by an optional comma "\([^\)]+\)(,?)"
## or any characters followed by a comma or end of line "[^,]+(,|$)"
## After that I save all the rest of the string to match it in
## following iterations.
while [[ $a1 =~ ([^\(,]*\([^\)]+\)(,?)|[^,]+(,|$))(.*) ]]; do
## BASH_REMATCH keeps grouped expressions. The first one
## has the data extracted between commas. This removes the
## trailing one.
elem="${BASH_REMATCH[1]%,}"
## Remove opening paren, if exists one.
elem="${elem/\(/}"
## Remove trailing paren, if exists one.
elem="${elem%)}"
## Add element to an array.
arr+=("$elem")
## Use the string left (fourth grouped expression in
## the regex) to continue matching elements.
a1="${BASH_REMATCH[4]}"
done
printf "%s\n" "${arr[@]}"
像这样运行它:
bash script.sh
它产生:
a
b
c
xxxd,e
sdff,g