16

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

This is some [text].
This [line] has [some more] text.

这变成:

This is some \macro{text}.
This \macro{line} has \macro{some more} text.
  • 这些对只出现在单独的行上,从不跨越多行。
  • 有时一行中可能有不止一对,但它们从不嵌套。
  • 如果在一行中单独发现一个括号,而没有一对,则不应更改它。

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

4

4 回答 4

33

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

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

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

  1. \[匹配方括号。由于[是一个有效的魔法正则表达式字符,反斜杠意味着匹配文字字符。
  2. \(...\)是一个捕获组。它捕获了我想要的正则表达式的一部分。我可以有许多捕获组,并且sed可以将它们引用为\1,\2等。
  3. 捕获组里面\(...\)。我有[^]]*
    1. [^...]语法表示任何字符但是。
    2. 表示除右大括号外的[^]]任何字符。
    3. 表示前面的*零个或多个。这意味着我正在捕获零个或多个不关闭方括号的字符。
  4. 表示右方\]括号

让我们看看这是 [some] more [text]这一行

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

如果我能保证每行都有一组方括号,那会容易得多。然后我可以这样做:

sed -i.bkup 's/\[\(.*\)\]/\\macro(\1)/g'

捕获组现在在方括号之间说出任何内容。然而,问题是正则表达式是贪婪的,这意味着我会从sin一直匹配some到 final tin text。下面的“x”显示了捕获组。[]显示我匹配的方括号:

 this is [some] more [text]
         [xxxxxxxxxxxxxxxx]

This became more complex because I had to match on characters that had special meaning to regular expressions, so we see a lot of backslashing. Plus, I had to account for regular expression greediness, which got the nice looking, non-matching string [^]]* to match anything not a closing bracket. Add in the square brackets before and after \[[^]]*\], and don't forget the \(...\) capture group: \[\([^]]*\)\]And you get one big mess of a regular expression.

于 2012-05-18T04:59:31.367 回答
16
sed -e 's/\[\([^]]*\)\]/\\macro{\1}/g' file.txt

这将查找一个左括号、任意数量的显式非右括号,然后是一个右括号。该组被括号捕获并插入到替换表达式中。

于 2012-05-18T04:02:27.760 回答
4

使用组

sed 's|\[\([^]]*\)\]|\\macro{\1}|g' file
于 2012-05-18T04:01:50.740 回答
2

以下表达式匹配模式[a-z, A-Z and space]并将其替换为\macro{<whatever was between the []>}

sed -e 's/\[\([a-zA-Z ]*\)\]/\\macro{\1}/g'

在表达式中,\( ... \)匹配组的形式可以稍后在替换中引用为\1

于 2012-05-18T04:01:48.490 回答