java - 具有事件驱动匹配的正则表达式实现?

标签 java javascript c++ c regex

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

我希望能够通过基于事件的模型在字符串中注册我正在寻找的一堆不同的正则表达式,通过正则表达式引擎提供字符串,然后正确地触发事件。有这样的事情存在吗?

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

谢谢

最佳答案

这在 Perl 正则表达式中很容易做到。您所做的就是以可以想象到的最简单的方式将事件标注插入到模式中的适当位置。

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

my $rx0 = /[+-]?(?:\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;

这是整个演示:

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";
}

运行时会产生以下结果:

        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谈论它,并有一个正确的模块链接。

关于java - 具有事件驱动匹配的正则表达式实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4317272/

相关文章:

java - Junit 和 EasyMock 意外失败

java - fromCallable 和 defer 有什么区别?

javascript - 将鼠标悬停在 anchor 旁边的图像上时显示隐藏 Div?

javascript - 如何使用 Google Maps API v3 和 Fusion Tables 打开/关闭图层?

c++ - 可以将 char* move 到 std::string 中吗?

java - 是否建议为 Maven 项目分离 Scala 和 Java 源文件?

java - 为什么输入在必填字段验证后保持值

javascript - 重写ajax jquery调用coffeescript

C++ 转换为货币值

c++ - VC9 中的字符串流错误? "Cannot access private member"