发新话题
打印

利用正则表达式

利用正则表达式

http://bbs.tecn.cn/viewthread.php?tid=229174&extra=page%3D1

怎样批量添加尾注的超链接?

可以利用正则表达式进行替换。

具体实现起来,我利用的是TextForever.exe提供的正则表达式替换功能。

建议往下看之前先请仔细看TextForever帮助文件关于正则表示式的说明,以及最好网上搜索一下正则表达式入门介绍之类的(正则表达式的引擎不同,具体写法也不太一样。UltraEdit-32和TextForever.exe使用的VBScipt写法就不太一样,vi里差的更远。但是原理都一样。)。有个大概印象就行。否则您未必能看懂我在说什么。


正则表达式入门可参考http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm

我看的就是这个。不过这个上面的语法有些TextForever不支持。


以word生成的html文件为例,把html或复制或另存为txt文件。这个时候注释符号一般是把数字放在中括号里,比如[1]、[2]、[3]、[4]……,我们用[\d](\d表示数字0~9)匹配这些[1]、[2]、[3]、[4]……,然后把匹配结果替换成<a name="" href="">匹配结果</a>即可。

首先,你必须确保文件里只要是以[\d]([]里面的数字的可以是一位、两位、三位……)形式出现的都是注释符号,而不是有其他意义的内容。

一般说来,一份文件里会成对出现[1]、[2]、[3]、[4]……,第一个[1](或[2]、[3]、[4]……)在正文里出现,第二个[1](或[2]、[3]、[4]……)在尾注部分的注释行起首出现。

因为正文里的[\d]和尾注部分的[\d]所要添加的HTML标记代码不同,因此正则表达式必须能够区别这个[\d]是哪个部分的。

我给出的区别办法是,尾注部分的[\d]的特征是一律在行首,而正文部分的[\d]不可能出现在行首,因为它总是出现在被注释的文字后面。(开始我比较蠢,把正文和尾注分开在两个文件里处理,然后又一个一个的合并。第二天才想出来怎么区别。)

先匹配正文中的[\d]

正则表达式:

([^\n])\[(\d{1,2})\]

会匹配文件里所有[0]、[1]、[2]、[3]、……[10]、[11]、……[99]这一百个符号,而且这个符号不能出现在行首,也就是说这个表达式是匹配正文里的[\d]。

如果文件里出现了[100]及以上,也就是说注释数不少于100,表达式可改为 ([^\n])\[(\d{1,3})\] 。同理,如果有不少于1000的注释,虽说这不太可能出现在一份文件里,写成([^\n])\[(\d{1,4})\]


部分文件原貌(这个一般不是我们处理时会遇到的情况。因为一般而言,正文部分的[\d]都出现在尾注部分的[\d]之前。这里我只是举例匹配非行首的[\d]和行首的[\d]的不同):

++++++++++++++++++++++++++++++++++

[1] “资产阶级”一词来源于法语bourgeois,指封建时代[2]的市民阶级。——辛达注[3]

++++++++++++++++++++++++++++++++++

里面的[2]、[3]被匹配了([3]并不在行首,而是在字符“注”后面,处于行尾,但是因为自动折行的原因,显示好像在行首。而真正在行首的[1]前面有不可见换行符\n。 注:图上见到的那个测试其实[1]前面没有换行符\n。因为是第一行,所以[1]没被匹配只是因为它是字符串首字符,前面没任何其他字符。但在实际处理的文件,注释部分不可能在第一行。截图的时候我还没想到这点,本想再新截一张,但转念一想,正则表达式很容易写错,有时甚至测试没看出有问题,也不代表这个表达式完全正是你想表达的意思。这里正好作个例子说明一下。)。


把这个表达式匹配的结果替换为

$1<a class="notelink" name="$2" href="#f$2">[$2]</a>

替换结果是:

++++++++++++++++++++++++++++++++++

[1] “资产阶级”一词来源于法语bourgeois,指封建时代<a class="notelink" name="2" href="#f2">[2]</a>的市民阶级。——辛达注<a class="notelink" name="3" href="#f3">[3]</a>

++++++++++++++++++++++++++++++++++

其中,class="notelink" 可以在样式表里指定注释符号的样式——比如上标、字体较小等等,如果不指定,可以省去。


然后处理尾注部分的[\d]

正则表达式

^\[(\d{1,2})\]

匹配文本中所有出现在行首(顶格行首,也就是前面没有空格,如果有请先用TextForever的段落合并把前面的空格删去)的[\d]。(因为以^匹配每行的开始位置所以Multiline属性要选中,即能够处理多行文本。)

匹配结果替换为

<br><a name="f$1" href="#$1">[$1]</a>

需要说明的是,必须把正文部分的替换放在第一行,尾注部分的放在第二行。即先替换正文,后替换尾注。因为如果先替换尾注,由于前后添加HTML标记,则尾注部分的[\d]将丧失行首的位置,和正文部分的[\d]无法区别。

当然,您非要先替换尾注部分也可以,正则表达式改成别的样子就行。

另外,注释符号也可能是(1)这种形式,或者其他形式。这时正则表达式需要改写。

比如如果尾注部分的[\d]前面有空格,也可以不删空格,表达式写成:

^\s*\[(\d{1,2})\]


其他闲话:

建议把这两个替换表达式保存起来,以备以后重复利用。正则表达式功能强大,使用得当的话能够节省大量繁琐劳动,而且也不是很难学。我学习正则表达式的经验是,多写多练。正好用TextForever.exe提供的测试功能拿来检测。TextForever帮助文件的 附录B 正则表达式语法(引自《VBScipt 用户指南》)里面有两项我感觉不太对。那里说

^\[ \t]*$    匹配一个空白行,

[.\n]        匹配包括 '\n' 在内的任何字符

这两个我就觉得不对。反正测试是没反应,也许是引擎不同的原因,又或者是理解的原因。

^\[ \t]*$  我是没看懂。

[.\n] 这个在TextForever里只匹配字符.和换行符\n

我在TextForever上测试的结果:

我理解的空白行:  ^[ \t]*\r\n

匹配包括硬回车在内的任何字符:  (.|\r\n)

表达式  begin(.|\r\n)*?end  可以匹配以begin开始的,以遇到的第一个end结束的跨行字符串。这个在处理文本时很有用。


再举一个例子,马版讨论合集txt里要处理大量的第一非空行和第二非空行掉换位置。

比如要把

+++++++++++++++++++++++++++++++++++
http://bbs.tecn.cn/viewthread.php?tid=184990&extra=page%3D18

职业学者#左翼文人


职业学者就是这样,没法认识得更高
            作者: 包子
            日期:   2004-06-04 18:11
++++++++++++++++++++++++++++++++++++++

改成

+++++++++++++++++++++++++++++++++++
职业学者#左翼文人

http://bbs.tecn.cn/viewthread.php?tid=184990&extra=page%3D18


职业学者就是这样,没法认识得更高
            作者: 包子
            日期:   2004-06-04 18:11
++++++++++++++++++++++++++++++++++++++

        
匹配前两个非空行(在一行之内的文字必须连续,中间不能有空格)的表达式可以写成

^\s*(\S+)\s*(\S+)\s*(\r\n)

注意这时Multiline(处理多行文本)不能选中。        

替换成

$2$3$3$1$3$3

我觉得说句废话,上面两张图是测试用的。真正批量调换位置时不是那个界面。

而且,里面有的文件第二非空行不是题目,而是“(主贴略)”,要掉换第一非空行和第三非空行。区别这个的表达式大概也能写出来。但是似乎第二非空行是“(主贴略)”的不多。我觉得可以不管这个特殊情况,等手工处理每个文件时,再调整。


注意事项:对正则表达式我也是新手,虽然上面的表达式和替换功能我做过试验,但是我不保证肯定不出问题,更不承诺为您使用上面的表达式所造成的后果承担任何责任。建议使用前先备份要处理的文件。替换以后检查一下。


[ 本帖最后由 柴荣 于 2007-12-6 16:34 编辑 ]

TOP

做人民日报资料汇编的时候,需要把发表时间加到标题后面去,这样在目录页检索的时候比较方便。

以前我是手工做这个活,一个题目上百篇文章,比较烦人。

最近重做,发现可以用正则表达式搬到。

我用的Vim编辑器。

标题和日期之间有一空行。原始资料就是这样。

日期行有时前面还有作者什么的,有的没有

首先需要通过正则表达式替换将每个标题前加4个=,标记标题

然后替换命令

:%s/^\(====.\+\)\n\n\(.\{-}\)\((\d\{4}.\+)\)/\1\3\r\2\3

主要是利用了正则表达式的捕获功能

TOP

资料格式的情况不同,表达式写法就不同。如果编辑器方言不同,写法也不同。

很灵活。这个没办法写一个以不变应万变的式子。

TOP

看了会EditPlus的正则表达式语法。功能比较弱。替换里面不支持回车键等等

同样的格式,EditPlus替换这样写:

查找内容:

(====.+)(\n)\n([^(]+)(\(.+\))

替换为:

\1\4\2\3\4

TOP

Vim就是强啊。就是稍有些难


替换里面不支持回车键等等
——————————
嗯? \n 不就是回车键吗?

TOP

哦,我错了。支持回车键。

不过总的说来,EditPlus的正则语法还是不够强大。没有懒惰模式。

如果不是经常需要处理大量文本,也没必要学Vim。比如以前我手工把日期加到标题后面去,可能要花几个小时,现在输入几个命令,几秒钟的事。这种情况学习Vim就是值得的。

[ 本帖最后由 柴荣 于 2008-9-11 00:25 编辑 ]

TOP

懒惰模式是什么?



用于批量添加脚注,Editplus可以,不过效果稍差一点
查找:
\[(.)\]    ——一位 [1][2]
\[(..)\]   ——两位 [30] [IX]

正文中的替换为 <a name="\1" href="#\1a">[\1]</a>
脚注中的替换为 <a name="\1a" href="#\1">[\1]</a>





一般说来,一份文件里会成对出现[1]、[2]、[3]、[4]……,第一个[1](或[2]、[3]、[4]……)在正文里出现,第二个[1](或[2]、[3]、[4]……)在尾注部分的注释行起首出现。
————————————————————————————————————————
哦,我是直接在HTML文件里打字校对,所以脚注中的[1]前面会有<p>等代码,不能用你的方法。看来以后应该把脚注前面的代码放到上一行末尾去,要不然不方便。

假如末尾脚注标志[1]放到行首,那么用Editplus:(对于一位的[1]、[X])
查找([^\n])\[(.)\]           ——正文中脚注标志
替换为\1<a name="\2" href="#\2a">[\2]</a>
查找\n\[(.)\]                ——脚注前的
替换为\n<a name="\1a" href="#\1">[\1]</a>

[ 本帖最后由 biaogang 于 2009-3-18 17:59 编辑 ]

TOP

懒惰模式和贪婪模式,你搜索一下就知道了。比如http://hi.baidu.com/tkocn/blog/item/a4f23c4ff622d33eaec3ab15.html

看来以后应该把脚注前面的代码放到上一行末尾去,要不然不方便。
------------------------------------
怎么放?手工放?脚注前面的<p>也可以写进正则表达式里。正文里的脚注的区别就是前面没有<p>

TOP

我自己制作网页的方法:

把相关文字复制到已设定好的Excel表中特定的地方,大小标题、引用、脚注、居中、居右,插入图片……等等,都只要在相应行的左栏输入相应数字,就可套上相应格式。然后,将转化好的内容转贴到Frontpage上去。少数地方再稍加修订。

缺点是:相应格式是套用在整个段落上的。所以无法对段落中部份文字进行设定(比如加粗)。这时可直接用手工完成,直接把<b></b>输入到文本中。

针对不同的网站或网页或电子书制作,可设定不同的EXCEL表。

Frontpage的替换功能比Word还强大,这点也很方便。

因此,关于《录入标准》,对我来说其中多数要求没什么用。

1、用Word格式或文本格式存档,对我来说都可以。有时我把Word文件转为无格式文本,有时Word文件中作者已定义了格式,我就先把它复制到Frontpage当中先处理一遍。

2、要求输入者学习网页编码,这很有必要。但要求打字时直接输入所有编码,我自己觉得没有必要,效率可能降低了。大小标题、脚注等等不一定要输入(但脚注统一为[#]格式很有必要,我也设置了公式,相应的编码也是自动添加的)

关于“脚注的位置不必拘泥于实体书中的位置,以便于阅读、对照为原则”。如果在网页上可以点击脚注可以找到注解,同样也可回到原文来,那么也无需要求“对照”。

3、关于表格。简单的表格,“用Tab制表键对齐文本”,以<pre> </pre>为标签,都无问题。较大的表格,我认为在文本里输入编码太麻烦了,可能也容易出错,不如直接制作网页,或在Word当中制作表格。

4、如果文件有多许多章节,那么最好能提供一份“目录”,那么,在各章之前加“=================”也可省去。

暂时想到这。

TOP

理想的情况是用脚本做所有的工作。

TOP

发新话题