0

我正在尝试编写一个表达式来替换一个名为 testRegex.csv 的文件

{"type":"MultiPolygon","coordinates":[[[-74.043886,40.690185 -74.040365,40.700704 -74.040288,40.700644 -74.03995,40.700891]]]}

有了这个

{"type":"MultiPolygon","coordinates":[[[[-74.043886,40.690185], [-74.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}

我试过以下

sed 's/(\W\d\d[.]\d*[,]\d\d[.]\d*)/[$1],/g' <testRegex.csv >testRegex2.csv
sed 's/(\W\d\d[\.]\d*[\,]\d\d[\.]\d*)/[$1]\,/g' <testRegex.csv >testRegex2.csv
sed 's/(\W\d\d\.\d*\,\d\d\.\d*)/[$1]\,/g' <testRegex.csv >testRegex2.csv

谁能明白为什么这些不起作用?

4

2 回答 2

2

尝试以下操作:

sed -E -e 's/([0-9-]+\.[0-9]*,[0-9-]+\.[0-9]*)/[\1],/g' -e 's/,]/]/'

请注意,在某些系统上,您可能需要将-E选项替换为-r,这是扩展正则表达式支持的选项。

于 2013-06-06T17:39:01.427 回答
0

我试图解决一个比公认答案稍微困难的问题——并开发了一个不会改变输出格式中的行的答案。这很困难,但可以做到(与传统的sedBRE 表示法相比,ERE 支持更简洁)。

BRE 符号

sed '/\([^[]\[\[\[\)\(\(\[[-+]*[0-9][0-9]*\.[0-9]*,[-+]*[0-9][0-9]*\.[0-9]*\], \)*\)\([-+]*[0-9][0-9]*\.[0-9]*,[-+]*[0-9][0-9]*\.[0-9]*\)/ {
: redo
s//\1\2[\4],/
t redo
s/,]]]/]]]/
}' <<'EOF'

{"type":"MultiPolygon","coordinates":[[[-74.043886,40.690185 -74.040365,40.700704 -74.040288,40.700644 -74.03995,40.700891]]]}
with this

{"type":"MultiPolygon","coordinates":[[[[-84.043886,40.690185], [-64.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}
EOF

ERE 符号

sed -E '/([^[]\[\[\[)((\[[-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+\], )*)([-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+)/ {
: redo
s//\1\2[\4],/
t redo
s/,]]]/]]]/
}' <<'EOF'

{"type":"MultiPolygon","coordinates":[[[-74.043886,40.690185 -74.040365,40.700704 -74.040288,40.700644 -74.03995,40.700891]]]}
with this

{"type":"MultiPolygon","coordinates":[[[[-84.043886,40.690185], [-64.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}

EOF

示例输出

{"type":"MultiPolygon","coordinates":[[[[-74.043886,40.690185], [-74.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]]}
with this

{"type":"MultiPolygon","coordinates":[[[[-84.043886,40.690185], [-64.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}

ERE的解释

/([^[]\[\[\[)((\[[-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+\], )*)([-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+)/

这可以分为 3 个子正则表达式:

  1. ([^[]\[\[\[) 这与前面有方括号以外的其他内容的三个方括号匹配。它变成\1了替换。
  2. ((\[[-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+\], )*) 这有两个捕获,但我真的对外部的感兴趣。内部查找一个方括号,后跟一个可能有符号的数字(坚持在小数点前至少使用一位数,小数点后至少使用一位数),逗号,另一个可能有符号数,右方括号(反斜杠是'不是绝对必要的),还有一个逗号和一个空格。这种内部捕获将是\3,并且可以重复零次或多次。外部捕获捕获 , 的所有重复\3,并称为\2。如果不使用外部捕获,则不是内部捕获仅捕获“方括号中的数字对”的最后一次重复,而通过两次捕获,您将获得所有重复。
  3. ([-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+) 这捕获了一对用逗号分隔的可能有符号的数字。

替换脚本使用了条件sed循环:

{
: redo
s//\1\2[\4],/
t redo
s/,]]]/]]]/
}

: redo设置标签。用方括号括起来的s//\1\2[\4],/相同信息替换第一个不带括号的“可能有符号的数字对,用逗号分隔”。添加g后缀没有任何作用;该模式必须适用于先前匹配的文本。因此,如果进行了替代,则t redo有条件地跳回标签。redofinals///删除在方括号中最后一对新数字之后添加的逗号。

请注意,BRE 正则表达式不坚持小数点后的数字;它可以做得更长,这样它就可以了([0-9]在四个小数点后添加一个额外的)。

于 2013-06-07T18:14:29.867 回答