待匹配文本:
THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.
ARGUMENT.
How a Ship having passed the Line was driven by Storms to the cold Country towards the South Pole; and how from thence she made her course to the tropical Latitude of the Great Pacific Ocean; and of the strange things that befell; and in what manner the Ancyent Marinere came back to his own Country.
I.
It is an ancyent Marinere,
And he stoppeth one of three:
"By thy long grey beard and thy glittering eye
"Now wherefore stoppest me?
1、正前瞻
假设要匹配单词ancyent,且要求紧随其后的单词是marinere(为与文件中的单词一致,我采用了古代拼写法)。要达到这个目的,我们可以使用正前瞻。
首先在RegExr桌面版程序中试一下。将下面这个不区分大小写的模式输入到顶部的文本框内:
(?i)ancyent(?= marinere)

由于我们使用了不区分大小写的选项(? i),就不必担心模式中用的大小写形式了。现在就是在每一行中寻找后跟marinere的单词ancyent。结果会在模式区域下面的文本区中标亮;但只有模式的第一部分(ancyent)是被标亮的,环视模式(Marinere)不会标亮。
现在使用Perl来做正前瞻。你可以写这样一个命令:
现在使用Perl来做正前瞻。你可以写这样一个命令:
perl -ne 'print if /(?i)ancyent(?= marinere)/' rime2.txt
其输出如下:
THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.
How a Ship having passed the Line was driven by Storms to the cold Country
towards the South Pole; and how from thence she made her course to the tropical
Latitude of the Great Pacific Ocean; and of the strange things that befell;
and in what manner the Ancyent Marinere came back to his own Country.
It is an ancyent Marinere,
"God save thee, ancyent Marinere!
"I fear thee, ancyent Marinere!
该诗有五行内容中的ancyent出现在marinere之前。如果要求ancyent之后的单词以大写或小写字母m开头,该如何做呢?可以这样:
perl -ne 'print if /(?i)ancyent (? =m)/' rime.txt
现在除了Marinere,跟在后面的还可以有man和Man:
And thus spake on that ancyent man,
And thus spake on that ancyent Man,
ack也可以使用环视功能,这是因为它是由Perl语言编写的。ack的命令行界面与grep十分相似。
试一下这个命令:
ack '(? i)ancyent (? =ma)' rime.txt
试一下这个命令:
ack '(? i)ancyent (? =ma)' rime.txt
你会看到高亮显示的结果,如图所示。

使用ack时,可以用命令行选项-i指定不区分大小写,而不使用嵌入选项(? i):
ack -i 'ancyent (? =ma)' rime.txt
使用ack时,可以用命令行选项-i指定不区分大小写,而不使用嵌入选项(? i):
ack -i 'ancyent (? =ma)' rime.txt
若要在ack的输出中添加行号以方便计数,可以采用多种方法。比如可以加上-H选项:
ack -Hi 'ancyent (? =ma)' rime.txt
也可以添加带有–output选项的代码:
ack -i --output '$.:$_' 'ancyent (? =ma)' rime.txt
这有点不太正统——关闭了标亮功能,但它确实起作用了。
2、反前瞻
反前瞻是对正前瞻的取反操作。这意味着要匹配某个模式时,需要在它后面找不到含有给定前瞻模式的内容。反前瞻的形式是:
(? i)ancyent (? ! marinere)
只有一个字符发生了变化:正前瞻的等号(=)变为反前瞻的感叹号(!)。下图所示为在Opera中执行反前瞻查找。

在Perl语言中,可以这样来使用反前瞻:
perl -ne 'print if /(? i)ancyent (? ! marinere)/' rime.txt
而我们会得到的结果是:
And thus spake on that ancyent man,
And thus spake on that ancyent Man,
在ack中,可以用
ack -i 'ancyent (? ! marinere)' rime.txt
得到相同结果。
3、正后顾
正后顾会查看左边的内容,这与正前瞻方向相反。其语法是:
(? i)(? <=ancyent) marinere
正后顾使用小于号(<),提醒你后顾是哪个方向。请在RegExr中试一下,看看有什么不同。被标亮的是marinere而不是ancyent。为什么?因为正后顾的模式是匹配的条件,不会包含在匹配结果中。
在Perl语言中这样做:
perl -ne 'print if /(? i)(? <=ancyent) marinere/' rime.txt
在ack中这样做:
ack -i '(? <=ancyent) marinere' rime.txt
4、反后顾
最后一种环视是反后顾。你能猜到它的工作原理吗?
反后顾会查看某个模式在从左至右的文本流的后面没有出现。同样,它有一个小于号(<),提醒后顾的是哪个方向。
请在RegExr中使用这个命令并查看结果:
(?1)(? <! ancyent) marinere
滚动到下方看看结果是什么。
然后用Perl语言尝试:
perl -ne 'print if /(? i)(? <! ancyent) marinere/' rime.txt
以下就是你会看到的结果,没有一个地方含有单词ancyent:
The Marinere hath his will.
The bright-eyed Marinere.
The bright-eyed Marinere.
The Marineres gave it biscuit-worms,
Came to the Marinere's hollo!
Came to the Marinere's hollo!
The Marineres all 'gan work the ropes,
The Marineres all return'd to work
The Marineres all 'gan pull the ropes,
"When the Marinere's trance is abated."
He loves to talk with Marineres
The Marinere, whose eye is bright,
最后在ack中这样做:
ack -i '(? <! ancyent) marinere' rime.txt
以上就是对前瞻和后顾的简单介绍,这是现代正则表达式的一个重要特性。

3899

被折叠的 条评论
为什么被折叠?



