仅使用未转义的分隔符拆分字符串

时间:2016-05-17 08:22:06

标签: regex bash perl sed

我想将,的字符串拆分为分隔符。我的问题是在某些情况下输入可能包含逗号。更改分隔符不是一种选择。我希望用户能够使用\转义逗号,因此我只想在, 上拆分,而不是\,上的,如下所示:

str="1,10,100,1\,000,10\,000,100\,000"
while [[ ${#str} -gt 0 ]]; do
    #Get index of delimiter
    index=$(echo "$str" | grep -boP '(?<!\\),' | head -c 1)

    #If index is empty, there is nothing to do
    if [[ -z "$index" ]]; then
        echo "$str"
        break
    fi

    #Get the next string we're looking for
    echo "$str" | cut -c1-$index
    #Cut the original string
    str=$(echo "$str" | cut -c$(($index+2))-${#str})
done

目前正在打印:

1
10
100
1\,000
10\,000
100\,000

但我希望它打印出来:

1
10
100
1,000
10,000
100,000

我现在可以使用sed\,替换为,,但对于相对简单的问题,这整个解决方案似乎相当庞大。有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

试试这个:

bash

使用$ sed 's/\([^\]\),/\1\n/g' <<< $str | while read -r line; do echo "-> $line"; done -> 1 -> 10 -> 100 -> 1\,000 -> 10\,000 -> 100\,000 单行:

while IFS= read -r line; do echo "-> $line"; done < <(sed 's/\([^\]\),/\1\n/g' <<< "$str")

根据@fedorqui的评论,通过这种方式,您可以避免打开子shell。

list = (ListView) rootView.findViewById(R.id.listAwards);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            FragmentManager fm = getFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            Fragment fragment = new AwardDetailFragment();
            ft.replace(R.id.fragmentlayout, fragment);
            ft.commit();
            Toast.makeText(getContext(),"Test",Toast.LENGTH_LONG).show();
        }
    });

答案 1 :(得分:1)

这是一种方式:

str="1,10,100,1\,000,10\,000,100\,000"
echo "$str" |sed -n 's/\([0-9]\+\(\\,[0-9]*\)*\),\+/\1\n/gp'
1
10
100
1\,000
10\,000
100\,000

使用tr,你可以删除那些反斜杠:

str="1,10,100,1\,000,10\,000,100\,000"
echo "$str" |sed -n 's/\([0-9]\+\(\\,[0-9]*\)*\),\+/\1\n/gp' |tr -d '\\'
1
10
100
1,000
10,000
100,000

答案 2 :(得分:0)

使用gnu awk您可以使用FPAT来使用复杂的正则表达式来分别解析每个字段:

str="1,10,100,1\,000,10\,000,100\,000"

awk -v FPAT='[^,\\\\]*(\\\\.[^,\\\\]*)*|[^,]*' '{
     for (i=1; i<=NF; i++) printf "%d: <%s>\n", i, $i}' <<< "$str"

1: <1>
2: <10>
3: <100>
4: <1\,000>
5: <10\,000>
6: <100\,000>