如何使用正则表达式(例如sed
)删除\index
任何标签内出现的所有标签\index
?
例如像这样的嵌套混乱:
\index{Test\index{test\index{test}}ing One\index{one} Two\index{two} Three\index{three}}
会变成
\index{Testing One Two Three}
谢谢
答案1
你可以使用循环。下面的代码会删除\index{foo}
前面有单词边界的部分。
sed -r ':a;s/\b\\index\{[^{}]+}//;ta' inputfile
对于给定的样本,它会产生:
\index{Testing One Two Three}
diff
但是,请注意不要使用正则表达式来解析和操作此类嵌套模式。如果这样做,请确保在更改前后观察输入。
编辑:解释:
先看替换命令:
s/\b\\index\{[^{}]+}//g
\b
\w
匹配单词字符和非单词字符之间的边界\W
。\\index\{
火柴\index{
[^{}]+}
匹配一个或多个不}
跟在后面的}
:a
是一个标签。 如果替换成功,则ta
分支到标签。a
因此,可以通过删除index{}
字符串中最里面的部分来实现,例如
\index{Test\index{test\index{test}}ing One\index{one} Two\index{two} Three\index{three}}
将转换为:
\index{Test\index{test}ing One\index{one} Two\index{two} Three\index{three}}
依此类推,直到替换失败。
答案2
无论 \index 位于何处,以下内容均有效,
sed -e 's/\\index{\([^]]*\)}/\\index{}/g' inputfile
除了...只要打开和关闭括号位于在同一条线上。sed确实有许多选项(P、N、D)用于处理在多行上完成的模式,但它们通过连接两行来工作。由于括号的 {} 模式可能在 3、4、..、n、... 行中结束,因此这需要一些编程。
或者,如果您满意只是定位匹配模式(IE,而不是替换它们),你可以使用:
pcregrep -M '\{(\s*.*\s*)*\}' test.txt
其中-M选项用于允许多行模式。这将找到零个或多个 (空格后跟 .* 再跟空格),前提是这些都被花括号括起来。