首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用事件驱动匹配的正则表达式实现?

使用事件驱动匹配的正则表达式实现?
EN

Stack Overflow用户
提问于 2010-12-01 02:47:23
回答 2查看 413关注 0票数 2

这听起来可能有点奇怪,但对我来说是非常有用的。是否有任何正则表达式实现(除java、javascript、c、c++之外的任何语言)使用基于事件的模型进行匹配?

我希望能够通过基于事件的模型在字符串中注册一组不同的正则表达式,通过regex引擎提供字符串,并正确触发事件。真的存在这样的东西吗?

我意识到这接近于重型词法分析器/解析器的领域,但如果可能的话,我更愿意远离它,因为我的搜索表达式需要是动态的(完全)。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-01 07:04:02

这在Perl正则表达式中很容易做到。您所要做的就是以最直接的方式在模式中的适当位置插入事件标注。

首先,想象一个从字符串中提取十进制数的模式:

代码语言:javascript
复制
my $rx0 = /[+-]?(?:\d+(?:\.\d*)?|\.\d+)/;

让我们展开它,这样我们就可以插入我们的标注:

代码语言:javascript
复制
my $rx1 = qr{
    [+-] ?
    (?: \d+
        (?: \. \d* ) ?
      |
        \. \d+
    )
}x;

对于标注,我只打印一些调试,但您可以做任何您想做的事情:

代码语言:javascript
复制
my $rx2 = qr{
    (?: [+-]                (?{ say "\tleading sign"                })
    ) ?
    (?: \d+                 (?{ say "\tinteger part"                })
        (?: \.              (?{ say "\tinternal decimal point"      })
            \d*             (?{ say "\toptional fractional part"    })
        ) ?
      |
        \.                  (?{ say "\tleading decimal point"       })
        \d+                 (?{ say "\trequired fractional part"    })
    )                       (?{ say "\tsuccess"                     })
}x;

下面是整个演示:

代码语言:javascript
复制
use 5.010;
use strict;

use utf8;

my $rx0 = qr/[+-]?(?:\d+(?:\.\d*)?|\.\d+)/;

my $rx1 = qr{
    [+-] ?
    (?: \d+
        (?: \. \d* ) ?
      |
        \. \d+
    )
}x;

my $rx2 = qr{
    (?: [+-]                (?{ say "\tleading sign"                })
    ) ?
    (?: \d+                 (?{ say "\tinteger part"                })
        (?: \.              (?{ say "\tinternal decimal point"      })
            \d*             (?{ say "\toptional fractional part"    })
        ) ?
      |
        \.                  (?{ say "\tleading decimal point"       })
        \d+                 (?{ say "\trequired fractional part"    })
    )                       (?{ say "\tsuccess"                     })
}x;

my $string = <<'END_OF_STRING';

    The Earth’s temperature varies between
    -89.2°C and 57.8°C, with a mean of 14°C.

    There are .25 quarts in 1 gallon.

    +10°F is -12.2°C.

END_OF_STRING

while ($string =~ /$rx2/gp) {
    printf "Number: ${^MATCH}\n";
}

它在运行时会生成以下代码:

代码语言:javascript
复制
        leading sign
        integer part
        internal decimal point
        optional fractional part
        success
Number: -89.2
        integer part
        internal decimal point
        optional fractional part
        success
Number: 57.8
        integer part
        success
Number: 14
        leading decimal point
        leading decimal point
        required fractional part
        success
Number: .25
        integer part
        success
Number: 1
        leading decimal point
        leading sign
        integer part
        success
Number: +10
        leading sign
        integer part
        internal decimal point
        optional fractional part
        success
Number: -12.2
        leading decimal point

为了便于维护,您可能需要安排一个更符合语法的正则表达式。当你想用它做一个递归下降解析器时,这也很有帮助。(是的,当然可以这样做:毕竟这是Perl。:)

看看this answer中的最后一个解决方案,我所说的语法正则表达式是什么意思。我在其他地方也有更大的例子。

但听起来您应该看看Damian Conway的Regexp::Grammars模块,它就是为这类事情而构建的。This question谈到了这一点,并且有一个指向模块本身的链接。

票数 3
EN

Stack Overflow用户

发布于 2010-12-01 02:52:29

您可能想要查看PIRE -一个非常快速的基于自动机的正则表达式引擎,经过调优可以快速地将无数行文本与许多正则表达式进行匹配。它在C中可用,并且有一些绑定。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4317272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档