Emacs正则表达式:匹配模式之间跨越多行的任何字符

时间:2017-07-19 04:49:19

标签: regex emacs

我想找到I - <characters> I -并将其替换为I - <characters>, I -

<characters>可以是Tab,Newline,Whitespace,*,&amp;等

例如:I - John M. Smith I -应替换为I - John M. Smith, I -

我尝试过类似的事情:

M-x Query replace regexp
\(I - \)\([a-z]+\) \(I - \)
\1\2, \3

它不起作用。你能帮忙吗?

1 个答案:

答案 0 :(得分:1)

这可以通过对正则表达式进行一些调整来实现。

输入

I - abc I - 
I - defgh I - 
I - John M. Smith I - 
I - 1234567 I - 
I - 12345
67 I - 
I - 12345
6789ABC
DE F G H IJK
LM N O P I - 

命令

M-x query-replace-regexp
\(I - \)\(\(.*?
\)*?.*?\)\( I - \)
\1\2,\4

请注意,上面的匹配正则表达式更像是......

\(I - \)\(\(.*?\n\)*?.*?\)\( I - \)

... \n代表换行符。在迷你缓冲区中,您需要输入\n作为C-q C-j

输出

I - abc, I - 
I - defgh, I - 
I - John M. Smith, I - 
I - 1234567, I - 
I - 12345
67, I - 
I - 12345
6789ABC
DE F G H IJK
LM N O P, I - 

说明

您的原始正则表达式匹配中间的字符类[a-z]+。但是,你也说过:

  

可以包括Tab,Newline,Whitespace,*,&amp;等

为了支持这一点,我们可以更改为.*以匹配任何字符。但是,这可能会消耗过多的输入,因此我们使用?进行惰性匹配。最后一个棘手的问题是多行匹配,因为你说可能有换行符。为了支持这一点,我们添加了\n处理。

只看中间部分,我们有......

\(\(.*?\n\)*?.*?\)

...你可以把它读成“匹配任意数量的字符(懒惰),然后换行任意次数(懒惰),再次跟随任意数量的字符(懒惰以免被消费到尾随I -部分行。)

参考