【python 正则表达式】python中使用正则表达式删除注释方法

更新时间:2017-09-08    来源:python    手机版     字体:

【www.bbyears.com--python】

关于多行匹配在python非贪婪、多行匹配正则表达式例子
一些regular的tips:

 代码如下

1 非贪婪flag

>>> re.findall(r"a(d+?)", "a23b")
        ["2"]
>>> re.findall(r"a(d+)", "a23b")
        ["23"]注意比较这种情况:

>>> re.findall(r"a(d+)b", "a23b")
        ["23"]
>>> re.findall(r"a(d+?)b", "a23b")
        ["23"]2 如果你要多行匹配,那么加上re.S和re.M标志
re.S:.将会匹配换行符,默认.不会匹配换行符

>>> re.findall(r"a(d+)b.+a(d+)b", "a23bna34b")
        []
>>> re.findall(r"a(d+)b.+a(d+)b", "a23bna34b", re.S)
        [("23", "34")]
>>>re.M:^$标志将会匹配每一行,默认^和$只会匹配第一行

>>> re.findall(r"^a(d+)b", "a23bna34b")
        ["23"]
>>> re.findall(r"^a(d+)b", "a23bna34b", re.M)
        ["23", "34"]但是,如果没有^标志,

>>> re.findall(r"a(d+)b", "a23bna23b")
        ["23", "23"]可见,是无需re.M

Popularity: 52%


这个问题, 之前我已经说过, 要点是使用[Ss]来模拟匹配换行符的点号. 原文在这里:《DIY万能通配符》. 可以以此写出这样的javascript代码来消除多行注释:

 

 代码如下  //to uncomment C-style multiple line comment
function uncomment_multi(str)
{
     return str.replace(//*[Ss]*?*//g, "");
}

单行注释之javascript实现(不完善)
单行注释并没有想像中的那样简单. 如果你认为只要 str.replace("//.*$")即可, 那么必须保证所要处理的文本都是最简单的, 如下:

 代码如下
 var pig="ase"; //this is a comment.

事实上这是行不通的. 现实程序中下面的例子比比皆是:

 

 代码如下  var url="http://iregex.org"; //this is my site.
var url="//not real comment here http://iregex.org"; //this is my site.

我尝试使用javascript写了个模拟否定前瞻的函数, 可以处理http://这种情况, 但是该函数看起来并不令人赏心悦目, 而且也不能处理引号中有双斜杠的情况. 我对javascript的正则式支持的特性之简陋实在很失望. 于是, 我求助于perl完成这一任务. 先看一下我写的javascript的删除单行注释的函数:

 代码如下  function uncomment_single(str)
{
    var result;
    var single=new RegExp("//.","ig");
    var start=0;
    while((result=single.exec(str))!=null)
    {
        var part=str.slice(start,result.index);
        var negLeft=new RegExp("http:$","i");
        if (! negLeft.test(part))
        {
            return str.slice(0,result.index);
        }
        start=result.index+result[0].length-1;
    }
    return str;
}

perl版删除注释思路及源码(相对完善)
待测试文本
好吧, 既然祭出了强大的perl, 之前的小打小闹似的例子就一边去吧. 我将使用如下相对复杂的文本来验证我的程序:

 

 代码如下   sdfasdf//real comment here//"

认真分析单行注释的特点
正确地分析其特点, 是写出合理高效的程序的前提. 观察可知, 单行注释的特点如下:

1.引号内(包括单引号和双引号)的双斜线不算注释.
2.引号是配对出现的, 两个引号之间的以反斜线转义掉的引号不算结束符. 例如"hello " //world", 这里的//world部分不能算做注释.
3.由连续的非引号非斜线部分组成的字符串也不是注释. 特别指出, 单个斜线不能算做注释. 为什么前半部分不但要非引号而且要非斜线呢? 因为[^""]+是有可能误匹配abcde//real comment "quoted string in comment"这样的情况, 因此我们归纳出一个条件[^""/]+; 又因为还要避免abcde/real comment "quoted string in comment"这样的情况, 还需要特别补充规定单个的斜线不是注释. 正则式是[^""/]|(? 4.除去上述内容以外, 以双斜线开始直至行尾的部分就是注释. 因为我们用到了行尾这个概念, 需要在正则式中特别指出是^$匹配行首行尾的多行模式. 使用//m来表示.
正则实现

 代码如下  #!/usr/bin/perl -w
$str = <<"EOF";
sdfasdf//real comment here//"
EOF
#print $str;
if ($str=~
    m%
        ^
            (?:
                [^""/]|
                (?                 (?[""])
                    (?:\ g{quote}|
                    (?!g{quote}).)*
                g{quote}
            )*
            (?//.*)
        $
    %xm)
    {
        print $+{comment};
}

几点补充
•该程序在perl5.10版才能运行成功. 因为用到了命名捕获(?[""])这样比较高阶的特性. 当然, 不使用5.10也并非没有办法, 我们大可以使用numbered capture, 只不过看起来更不直观罢了.
•匹配结束后, 命名捕获都保存在hash表%+中了. 使用print $+{comment}这样的方式可以方便地调用.
•指定了x模式, 以便加入空白字符和换行, 让正则表达式看起来有层次感. 事实上, 对于复杂的正则表达式, 不使用x模式是极其不明智的做法.
•为了在字串中方便地表示单双引号, 使用了heredoc的方式. 个人觉得不如python的三重引号方便.

本文来源:http://www.bbyears.com/jiaocheng/35429.html

猜你感兴趣

热门标签

更多>>

本类排行