花了一点时间,但在这里:
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'
捕获组现在在方括号之间说出任何内容。然而,问题是正则表达式是贪婪的,这意味着我会从s
in一直匹配some
到 final t
in 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.