【问题标题】:replacing nested backreferences in regular expression替换正则表达式中的嵌套反向引用
【发布时间】:2019-02-26 22:58:16
【问题描述】:

我从 Excel 电子表格中提取了一列,其中一些单元格包含多行,而有些则不包含。多行单元格由引号分隔。我想用“,”替换那些多行单元格中的返回。所以我的文件看起来像这样:

"Alpha
 Beta
 Gamma"
 123
 456
"Apple
 Banana
 Cherry"
 789
 this is a single-line cell

我的目标是

 Alpha, Beta, Gamma
 123
 456
 Apple, Banana, Cherry
 789
 this is a single-line cell

我可以编写一个使用嵌套模式捕获这些多行单元格的模式,但我不知道如何“到达内部”以获取反向引用。

"(([^"]+)\n)+([^"]+)"

【问题讨论】:

  • 没有嵌套的反向引用。正则表达式不是这样工作的,重复的捕获组只在最后一次迭代中保持最后一次匹配。
  • 我有一种感觉。谢谢。

标签: regex grep nested pcre


【解决方案1】:

试试:

$ sed '/^"/{:a; /"$/bb; N; ba; :b; s/\n//g}' file
"Alpha Beta Gamma"
 123
 456
"Apple Banana Cherry"
 789
 this is a single-line cell

工作原理

  • /^"/{...}

    对于任何以" 开头的行,都会执行大括号中的命令。

  • :a

    这会创建一个标签a

  • /"$/bb

    如果当前模式空间以" 结尾,则分支到标签b

  • N

    将新行读入模式空间。

  • ba

    分支回到标签a

  • :b

    这定义了标签b

  • s/\n//g

    从模式空间中删除所有换行符。

【讨论】:

  • 谢谢。我不得不将替换更改为 s/\n/、/g,但我很欣赏一步一步的操作。这只是强化了我,我需要分解并学习 sed 或 awk。
【解决方案2】:

使用 GNU awk 进行多字符 RS 和 RT:

$ awk -v RS='"[^"]+"|[^"\n]+' '$0=RT{gsub(/^\s+|\s+$|"/,""); gsub(/\n/,","); print}' file
Alpha, Beta, Gamma
123
456
Apple, Banana, Cherry
789
this is a single-line cell

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    相关资源
    最近更新 更多