﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-柯枫-随笔分类-Linux</title><link>http://www.cppblog.com/kefeng/category/15144.html</link><description>我们应该做的并不是远方模糊不清的事，而是手边确定无疑的事情。</description><language>zh-cn</language><lastBuildDate>Thu, 21 Oct 2010 08:05:28 GMT</lastBuildDate><pubDate>Thu, 21 Oct 2010 08:05:28 GMT</pubDate><ttl>60</ttl><item><title>Vim正则表达式[转]</title><link>http://www.cppblog.com/kefeng/archive/2010/10/20/130574.html</link><dc:creator>柯枫</dc:creator><author>柯枫</author><pubDate>Wed, 20 Oct 2010 07:57:00 GMT</pubDate><guid>http://www.cppblog.com/kefeng/archive/2010/10/20/130574.html</guid><wfw:comment>http://www.cppblog.com/kefeng/comments/130574.html</wfw:comment><comments>http://www.cppblog.com/kefeng/archive/2010/10/20/130574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kefeng/comments/commentRss/130574.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kefeng/services/trackbacks/130574.html</trackback:ping><description><![CDATA[<p>Vim中的正则表达式功能很强大，如果能自由运用，则可以完成很多难以想象的操作。</p>
<p>如果你比较熟悉Perl的正规表达式，可以直接参照<a  href="http://www.idv2.com/vimwiki/index.php?%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F#perldiff"><font color="#336699">与Perl正则表达式的区别</font></a>一节。</p>
<h2><strong><u>一、使用正则表达式的命令</u></strong></h2>
<p>使用正则表达式的命令最常见的就是<strong> </strong><font color="#ff0000"><strong>/ （搜索）</strong></font>命令。其格式如下：</p>
<pre><font color="#ff0000"><strong>/正则表达式</strong></font></pre>
<p>另一个很有用的命令就是 <font color="#ff0000"><strong>:s（替换）</strong></font>命令，将第一个//之间的正则表达式替换成第二个//之间的字符串。</p>
<pre><font color="#ff0000"><strong>:s/正则表达式/替换字符串/选项</strong></font></pre>
<p>在学习正则表达式时可以利用 <strong>/</strong> 命令来练习。</p>
<h2><strong><u>二、元字符</u></strong></h2>
<p>元字符是具有特殊意义的字符。使用元字符可以表达<strong>任意字符</strong>、<strong>行首</strong>、<strong>行 尾</strong>、<strong>某几个字符</strong>等意义。</p>
<p><strong>元字符一览</strong></p>
<div class="ie5">
<table class="style_table" border="0" height="282" cellspacing="1" width="625">
    <thead>
        <tr>
            <td class="style_td">元字符</td>
            <td class="style_td">说明</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>.</strong></font></td>
            <td class="style_td">匹配任意一个字符</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>[abc]</strong></font></td>
            <td class="style_td">匹配方括号中的任意一个字符。可以使用-表示字符范围，<br>
            如<strong>[a-z0-9]</strong>匹 配小写字母和阿拉伯数字。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>[^abc]</strong></font></td>
            <td class="style_td">在方括号内开头使用<strong>^</strong>符号，表示匹配除方括号中字符之外的任意字符。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\d</strong></font></td>
            <td class="style_td">匹配阿拉伯数字，等同于<strong>[0-9]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\D</strong></font></td>
            <td class="style_td">匹配阿拉伯数字之外的任意字符，等同于<strong>[^0-9]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\x</strong></font></td>
            <td class="style_td">匹配十六进制数字，等同于<strong>[0-9A-Fa-f]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\X</strong></font></td>
            <td class="style_td">匹配十六进制数字之外的任意字符，等同于<strong>[^0-9A-Fa-f]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\w</strong></font></td>
            <td class="style_td">匹配单词字母，等同于<strong>[0-9A-Za-z_]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\W</strong></font></td>
            <td class="style_td">匹配单词字母之外的任意字符，等同于<strong>[^0-9A-Za-z_]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\t</strong></font></td>
            <td class="style_td">匹配&lt;TAB&gt;字符。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\s</strong></font></td>
            <td class="style_td">匹配空白字符，等同于<strong>[ \t]</strong>。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\S</strong></font></td>
            <td class="style_td">匹配非空白字符，等同于<strong>[^ \t]</strong>。</td>
        </tr>
    </tbody>
</table>
</div>
<p>另外，如果要查找字符 *、.、/等，则需要在前面用 <strong>\</strong> 符号，表示这不是元字符，而只是普通字符而已。</p>
<div class="ie5">
<table class="style_table" border="0" height="120" cellspacing="1" width="236">
    <thead>
        <tr>
            <td class="style_td">元字符</td>
            <td class="style_td">说明</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\*</strong></font></td>
            <td class="style_td">匹配 * 字符。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\.</strong></font></td>
            <td class="style_td">匹配 . 字符。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\/</strong></font></td>
            <td class="style_td">匹配 / 字符。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\\</strong></font></td>
            <td class="style_td">匹配 \ 字符。</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\[</strong></font></td>
            <td class="style_td">匹配 [ 字符。</td>
        </tr>
    </tbody>
</table>
</div>
<h3>表示数量的元字符</h3>
<div class="ie5">
<table class="style_table" border="0" height="153" cellspacing="1" width="214">
    <thead>
        <tr>
            <td class="style_td">元字符</td>
            <td class="style_td">说明</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>*</strong></font></td>
            <td class="style_td">匹配0-任意个</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\+</strong></font></td>
            <td class="style_td">匹配1-任意个</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\?</strong></font></td>
            <td class="style_td">匹配0-1个</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\{n,m}</strong></font></td>
            <td class="style_td">匹配n-m个</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\{n}</strong></font></td>
            <td class="style_td">匹配n个</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\{n,}</strong></font></td>
            <td class="style_td">匹配n-任意个</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\{,m}</strong></font></td>
            <td class="style_td">匹配0-m个</td>
        </tr>
    </tbody>
</table>
</div>
<h3>表示位置的符号</h3>
<div class="ie5">
<table class="style_table" border="0" height="98" cellspacing="1" width="208">
    <thead>
        <tr>
            <td class="style_td">元字符</td>
            <td class="style_td">说明</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>$</strong></font></td>
            <td class="style_td">匹配行尾</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>^</strong></font></td>
            <td class="style_td">匹配行首</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\&lt;</strong></font></td>
            <td class="style_td">匹配单词词首</td>
        </tr>
        <tr>
            <td class="style_td"><font color="#ff0000"><strong>\&gt;</strong></font></td>
            <td class="style_td">匹配单词词尾</td>
        </tr>
    </tbody>
</table>
</div>
<p><strong>使用例</strong></p>
<pre>/char\s\+[A-Za-z_]\w*;                 " 查找所有以char开头，之后是一个以上的空白，<br>                                             " 最后是一个标识符和分号<br>/\d\d:\d\d:\d\d                        " 查找如 17:37:01 格式的时间字符串<br>:g/^\s*$/d                             " 删除只有空白的行<br>:s/\&lt;four\&gt;/4/g                        " 将所有的four替换成4，但是fourteen中的four不替换</pre>
<h2><strong><u>三、替换变量</u></strong></h2>
<p>在正规表达式中使用 <font color="#ff0000"><strong>\(</strong></font> 和<font color="#ff0000"> <strong>\)</strong> </font>符号括起正规表达式，即可在后面使用<font color="#ff0000"><strong>\1</strong></font>、<font color="#ff0000"><strong>\2</strong></font> 等变量来访问 <strong>\(</strong> 和 <strong>\)</strong> 中的内容。</p>
<p><strong>使用例</strong></p>
<pre>/\(a\+\)[^a]\+\1                                          " 查找开头和结尾处a的个数相同的字符串，<br>                                                                  " 如 aabbbaa，aaacccaaa，但是不匹配 abbbaa<br>:s/\(http:\/\/[-a-z\._~\+%\/]\+\)/&lt;a href="\1"&gt;\1&lt;\/a&gt;/   " 将URL替换为&lt;a href="http://url"&gt;http://url&lt;/a&gt;的格式<br>:s/\(\w\+\)\s\+\(\w\+\)/\2\t\1                            " 将 data1 data2 修改为 data2 data1</pre>
<h2><u><strong>四、函数式</strong></u></h2>
<p>在替换命令 <strong>s///</strong> 中可以使用函数表达式来书写替换内容，格式为</p>
<pre><strong><font color="#ff0000">:s/替换字符串/\=函数式</font></strong></pre>
<p>在函数式中可以使用 submatch(1)、submatch(2) 等来引用 <strong>\1</strong>、<strong>\2</strong>  等的内容，而submatch(0)可以引用匹配的整个内容。</p>
<p><strong>使用例</strong></p>
<pre>:%s/\&lt;id\&gt;/\=line(".")                              " 将各行的 id 字符串替换为行号<br>:%s/^\&lt;\w\+\&gt;/\=(line(".")-10) .".". submatch(1)    " 将每行开头的单词替换为 (行号-10).单词 的格式，<br>                                                           " 如第11行的 word 替换成 1. word</pre>
<h2><u><strong>五、与Perl正则表达式的区别</strong></u></h2>
<p><strong>元字符的区别</strong></p>
<table class="style_table" border="0" height="99" cellspacing="1" width="300">
    <thead>
        <tr>
            <td class="style_td">Vim语法</td>
            <td class="style_td">Perl语法</td>
            <td class="style_td">含义</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="style_td">\+</td>
            <td class="style_td">+</td>
            <td class="style_td">1-任意个</td>
        </tr>
        <tr>
            <td class="style_td">\?</td>
            <td class="style_td">?</td>
            <td class="style_td">0-1个</td>
        </tr>
        <tr>
            <td class="style_td">\{n,m}</td>
            <td class="style_td">{n,m}</td>
            <td class="style_td">n-m个</td>
        </tr>
        <tr>
            <td class="style_td">\(和\)</td>
            <td class="style_td">(和)</td>
            <td class="style_td">分组</td>
        </tr>
    </tbody>
</table>
<br>
<br>
<h1><u><strong>六、vi 正则表达式练习</strong></u></h1>
<br>
<p>闲言碎语不要讲&#8230;例子说明一切，比如下面这段我需要换成 ubb 标签</p>
<p> </p>
<p> </p>
<p>vim 命令模式，输入</p>
<p>:%s/.*src=&#8221;([^"]*)&#8221;[^&gt;]*&gt;/[img]1[/img]/g</p>
<p>替换为</p>
<p>[img ]gu.jpg[ /img]</p>
<p>[img ]os.jpg[ /img]</p>
<p>[img ]hu.jpg[ /img]</p>
<p>[img ]ang.jpg[ /img]</p>
<p>解释如下：</p>
<p>:</p>
<p>命令执行状态</p>
<p>%s</p>
<p>表示查找并替换</p>
<p>%s/<span style="color: red;">a</span>/<span style="color: green;">b</span>/<span style="color: blue;">g</span></p>
<p><span style="color: red;">a</span> 被查找的字符串（正则匹配）；<span style="color: green;">b</span> 要替换成的文字；<span style="color: blue;">g</span>  表示全局搜索替换（否则只处理找到的第一个结果）</p>
<p><span style="color: red;">(</span>[^"]*<span style="color: red;">)</span></p>
<p>表示非引号的字符N个；外面 <span style="color: red;">()</span> 表示后面替换要用（用  1,&#8230;,9等引用）</p>
<p>[/img]</p>
<p>/ 需要被  转义</p>
<p>与其它工具正则不一样的地方在于 () 也必须 ()，怪不得我老是弄不出来。</p>
<p>相关资料：</p>
<p>via <a  href="http://net.pku.edu.cn/%7Eyhf/tao_regexps_zh.html" rel="external" class="ubblink">http://net.pku.edu.cn/~yhf/tao_regexps_zh.html</a></p>
<p>vi 命令   作用</p>
<p>:%s/ */ /g  把一个或者多个空格替换为一个空格。</p>
<p>:%s/ *$//  去掉行尾的所有空格。</p>
<p>:%s/^/ /  在每一行头上加入一个空格。</p>
<p>:%s/^[0-9][0-9]* //  去掉行首的所有数字字符。</p>
<p>:%s/b[aeio]g/bug/g  将所有的bag、beg、big和bog改为bug。</p>
<p>:%s/t([aou])g/h1t/g   将所有tag、tog和tug分别改为hat、hot和hug（注意用group的用法和使用1引用前面被匹配的字符）。</p>
<p><font color="#ff0000"><strong>Sed</strong></font></p>
<p>Sed是Stream EDitor的缩写，是Unix下常用的基于文件和管道的编辑工具，可以在手册中得到关于sed的详细信息。</p>
<p>这里是一些有趣的sed脚本，假定我们正在处理一个叫做price.txt的文件。注意这些编辑并不会改变源文件，sed只是处理源文件的每一行并 把结果显示在标准输出中（当然很容易使用重定向来定制）：</p>
<p>sed脚本       描述</p>
<p>sed &#8217;s/^$/d&#8217; price.txt   删除所有空行</p>
<p>sed &#8217;s/^[  ]*$/d&#8217; price.txt   删除所有只包含空格或者制表符的行</p>
<p>sed &#8217;s/&#8221;//g&#8217; price.txt   删除所有引号</p><img src ="http://www.cppblog.com/kefeng/aggbug/130574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kefeng/" target="_blank">柯枫</a> 2010-10-20 15:57 <a href="http://www.cppblog.com/kefeng/archive/2010/10/20/130574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>