花了一点时间,但在这里:
sed -i.bkup 's/\[\([^]]*\)\]/\\macro{\1}/g' test.txt
让我们看看我是否可以解释这个正则表达式:
\[匹配方括号。由于[是一个有效的魔法正则表达式字符,反斜杠意味着匹配文字字符。
- 这
\(...\)是一个捕获组。它捕获了我想要的正则表达式的一部分。我可以有许多捕获组,并且sed可以将它们引用为\1,\2等。
- 捕获组里面
\(...\)。我有[^]]*。
[^...]语法表示任何字符但是。
- 表示除右大括号外的
[^]]任何字符。
- 表示前面的
*零个或多个。这意味着我正在捕获零个或多个不关闭方括号的字符。
- 表示右方
\]括号
让我们看看这是 [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.