如何用sed替换其他语法的成对方括号?

Vil*_*age 9 bash sed

我想替换文件中的所有方括号对,例如[some text],用\macro{some text},例如:

This is some [text].
This [line] has [some more] text.
Run Code Online (Sandbox Code Playgroud)

这变为:

This is some \macro{text}.
This \macro{line} has \macro{some more} text.
Run Code Online (Sandbox Code Playgroud)
  • 这些对只出现在单独的行上,从不跨越多行.
  • 有时在一行上可能有多个对,但它们从不嵌套.
  • 如果在一条线上单独找到一个括号,没有一对,则不应更改它.

如何用这段代码替换这些括号对?

Dav*_* W. 25

花了一点时间,但在这里:

sed -i.bkup  's/\[\([^]]*\)\]/\\macro{\1}/g' test.txt
Run Code Online (Sandbox Code Playgroud)

让我们看看我是否可以解释这个正则表达式:

  1. \[是匹配方括号.由于[是一个有效的魔术正则表达式字符,反斜杠意味着匹配文字字符.
  2. (...)是一个捕获组.它捕获了我想要的正则表达式的一部分.我可以有很多的捕捉组,并在sed我可以引用它们作为\1,\2等等.
  3. 在捕获组内\(...\).我有[^]]*.
    1. [^...]语法是指任何字符,但.
    2. [^]]装置中的任何字符,但一个右括号.
    3. *装置零个或多个先前的.这意味着我正在捕获零个或多个不关闭方括号的字符.
  4. \]装置中的右方括号

让我们来看看[更多] [文字]

  • 在上面的#1中,我捕获了一些单词前面的第一个开放方括号.但是,它不在捕获组中.这是我要替换的第一个角色.
  • 我现在开始一个捕获组.我根据3.2和3.3以上捕获,以字母s一些尽可能多的字符可能是不关闭方括号中.这意味着我匹配[some,但只捕获some.
  • 在#4中,我结束了我的捕获组.我已经匹配替换目的[some,现在我匹配最后一个结束方括号.这意味着我匹配[some].请注意,正则表达式通常是贪婪的.我将在下面解释为什么这很重要.
  • 现在,我可以匹配替换字符串.这更容易.是的\\macro(\1).该\1由我捕获组所取代.这\\只是一个反斜杠.因此,我将替换[some]\macro{some}.

如果可以保证每行中有一组方括号,那将会容易得多.然后我可以做到这一点:

sed -i.bkup 's/\[\(.*\)\]/\\macro(\1)/g'
Run Code Online (Sandbox Code Playgroud)

捕获组现在在方括号之间说任何东西.然而,问题是,正则表达式是贪婪的,这意味着我会从匹配ssome一路到最后t文本.下面的"x"表示捕获组.在[]显示的方括号我匹配的:

 this is [some] more [text]
         [xxxxxxxxxxxxxxxx]
Run Code Online (Sandbox Code Playgroud)

这变得更加复杂,因为我必须匹配正则表达式具有特殊含义的字符,所以我们看到了很多反斜杠.另外,我不得不考虑正则表达式的贪婪,这得到了漂亮的,不匹配的字符串,[^]]*以匹配任何不是结束括号.在前后方括号中添加,\[[^]]*\]不要忘记\(...\)捕获组:\[\([^]]*\)\]你得到一个正则表达式的大混乱.


小智 11

sed -e 's/\[\([^]]*\)\]/\\macro{\1}/g' file.txt
Run Code Online (Sandbox Code Playgroud)

这将查找一个左括号,任意数量的明确非关闭括号,然后是一个右括号.该组被parens捕获并插入替换表达式中.