声明: 如需转载本博原创文章,请注明:转载自九九志 • 重阳 (http://www.99log.com)
通过前两节(一、二)的介绍的方法,已经可以通过正则表达式替换完成很多的批量文件修改工作了,不过还有一些限制。看看下面这篇短文(文件名cyj.txt):
重阳节,农历九月初九,二九相重,称为"重九"。汉中叶以后的儒家阴阳观,有六阴 九阳。九是阳数,固重九亦叫"重阳"。民间在该日有登高的风俗,所以重阳节又称"登 高节"。还有重九节、茱萸、菊花节等说法。
唐代诗人沈佺期《九日临渭亭侍宴应制得长字》诗:"魏文颂菊蕊,汉武赐萸囊……,年 年重九庆,日月奉天长"。《旧唐书·王勃传》记载:王勃的《滕王阁序》就是在重阳 节这一天写出来的。当时王勃的父亲担任交趾令,王勃前往探视父亲,九月九日路过 南昌时,洪州牧阎伯屿正在重修的滕王阁中宴请宾客及部属,他想夸耀女婿吴子章 (孟学士)的才气,便事先拿出纸笔请宾客动笔作序,所有的宾客都知道他的用意, 没有人敢作。却不料王勃事先并不知道州牧的用心,于是毫不谦让接过纸笔。州牧原 本心中十分生气,立即派人在旁边看王勃书写,谁知道王勃才气不凡,蓄积已久的心 情完全发泄出来,文章越写越好,当写到"落霞与孤鹜齐飞,秋水共长天一色"的词句 时,忍不住拍案叫绝!王勃从此一举名震诗坛。
文中的双引号都是用的半角的,而且不分左右。如何能把半角的双引号替换为全角并且能正确的使用“”呢?如果熟悉正则表达式的话,应该很容易就能想到使用s/"(.*?)"/“\1”/g来进行替换。那么,我们尝试以下命令:
Windows环境: perl -p -e "s/\"(.*?)\"/“\1”/g" cyj.txt
Linux环境: perl -p -e 's/"(.*?)"/“\1”/g' cyj.txt
上面的命令行中没有指定 -i 参数,所以替换后的结果会直接输出到屏幕上而不是写入文件中,很多时候,我们都需要用这种方法先看看替换结果是否正确。运行后,可以看到屏幕上输出以下替换结果:
重阳节,农历九月初九,二九相重,称为“重九”。汉中叶以后的儒家阴阳观,有六阴 九阳。九是阳数,固重九亦叫“重阳”。民间在该日有登高的风俗,所以重阳节又称"登 高节"。还有重九节、茱萸、菊花节等说法。
唐代诗人沈佺期《九日临渭亭侍宴应制得长字》诗:"魏文颂菊蕊,汉武赐萸囊……,年 年重九庆,日月奉天长"。《旧唐书·王勃传》记载:王勃的《滕王阁序》就是在重阳 节这一天写出来的。当时王勃的父亲担任交趾令,王勃前往探视父亲,九月九日路过 南昌时,洪州牧阎伯屿正在重修的滕王阁中宴请宾客及部属,他想夸耀女婿吴子章 (孟学士)的才气,便事先拿出纸笔请宾客动笔作序,所有的宾客都知道他的用意, 没有人敢作。却不料王勃事先并不知道州牧的用心,于是毫不谦让接过纸笔。州牧原 本心中十分生气,立即派人在旁边看王勃书写,谁知道王勃才气不凡,蓄积已久的心 情完全发泄出来,文章越写越好,当写到“落霞与孤鹜齐飞,秋水共长天一色”的词句 时,忍不住拍案叫绝!王勃从此一举名震诗坛。
仔细观察后发现,有好几处双引号都没有正确替换。第一节中介绍正则表达式参数 g 时提到过,perl –p命令行每次读取文件中的一行进行处理,所以对于跨行的双引号对,上述的命令行就不能正确匹配处理了。
要解决这个问题,需要使用perl的另一个命令行参数 -0 ,它的作用是为perl每次读取文件内容指定一个分隔符,-0 参数后紧跟一个八进制数或十六进制数,若是十六进制数,需要使用前缀x。比如 –040 和 -0x20 都表示使用空格作为分隔符。而 -0 参数有几个特别的用法用得非常广泛,分别是 -0、-00、和 -0777 。单独指定 -0 表示以 null 字符串作为分格符,在处理普通的文本文件时一般用不上它。 -00 表示使用段落模式,也就是每次读取一个段落。-0777 表示一次读取整个文件。上例中的短文,由于不存在跨越段落的双引号对,使用 -00 和 -0777 都是适合的。
不过,就算加上了 -0777 这样的参数,结果确还是和上一条命令一模一样,怎么回事呢?原因是正则表达式s/"(.*?)"/“\1”/g中的句点 . 号不能匹配换行符。使用正则表达式的 s 参数使得句点可以匹配换行符。所以以下命令行可以成功替换短文中所有的双引号:
Windows环境: perl -0777 –p -i.bak -e "s/\"(.*?)\"/“\1”/gs" cyj.txt
Linux环境: perl –0777 -p -i.bak -e 's/"(.*?)"/“\1”/gs' cyj.txt
-i.bak 参数前两节中都有说明,这里就不复述了。命令运行后,cyj.txt的内容被修改成如下内容:
重阳节,农历九月初九,二九相重,称为“重九”。汉中叶以后的儒家阴阳观,有六阴 九阳。九是阳数,固重九亦叫“重阳”。民间在该日有登高的风俗,所以重阳节又称“登 高节”。还有重九节、茱萸、菊花节等说法。
唐代诗人沈佺期《九日临渭亭侍宴应制得长字》诗:“魏文颂菊蕊,汉武赐萸囊……,年 年重九庆,日月奉天长”。《旧唐书·王勃传》记载:王勃的《滕王阁序》就是在重阳 节这一天写出来的。当时王勃的父亲担任交趾令,王勃前往探视父亲,九月九日路过 南昌时,洪州牧阎伯屿正在重修的滕王阁中宴请宾客及部属,他想夸耀女婿吴子章 (孟学士)的才气,便事先拿出纸笔请宾客动笔作序,所有的宾客都知道他的用意, 没有人敢作。却不料王勃事先并不知道州牧的用心,于是毫不谦让接过纸笔。州牧原 本心中十分生气,立即派人在旁边看王勃书写,谁知道王勃才气不凡,蓄积已久的心 情完全发泄出来,文章越写越好,当写到“落霞与孤鹜齐飞,秋水共长天一色”的词句 时,忍不住拍案叫绝!王勃从此一举名震诗坛。
最后,再解释一下perl正则表达式的 s 参数和 m 参数。从上例中我们可以看到,s 参数使得句点可以匹配换行符而不带 s 参数则不可以。s 启用了正则表达式的“单行模式”,使的换行符和其他字符一样,可以被句点匹配。 而 m 启用的是多行模式,它影响的不是句点符,而是正则表达式中的另外两个特殊符号 ^ 和 $ ,它们分别匹配行首和行尾这两个位置而不是任何字符,不指定 m 参数时,^ 和 $ 分别匹配的是字符串的开始和结尾处,而指定 m 参数后,^ 和 $ 分别匹配每一行的行首和行尾。由于 s 和 m 分别影响不同特殊字符的匹配行为,所以它们可以组合使用,同时指定 s 和 m 参数的结果是句点可以匹配换行符的同时 ^ 和 $ 还能匹配每一行的行首和行尾。
总结:
| 一 | 二 | 三 | 四 | 五 | 六 | 日 |
|---|---|---|---|---|---|---|
| « 三 | ||||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 | ||||
One Response
laudy
四月 7th, 2009 at 2:07 下午
1强,您这是以前就会了的,还是临时学的?要是临时学的,这么短时间学这么深,那我就太佩服您了!!!
RSS feed for comments on this post · TrackBack URI
Leave a reply