迭代正则表达式匹配

时间:2009-11-18 19:46:32

标签: c++ regex parsing

我们已经相当熟练地生成各种正则表达式来匹配输入字符串,但我们已经被要求尝试迭代地验证这些字符串。有没有一种简单的方法可以将输入字符串与正则表达式迭代匹配?

例如,采用以下正则表达式:

[EW]\d{1,3}\.\d

当用户进入“E123.4”时,符合正则表达式。如何在用户输入时验证用户的输入?我可以将字符串“E1”与正则表达式部分匹配吗?

有没有办法说输入字符串只与输入部分匹配?或者有没有办法根据字符串长度自动生成主表达式中的子表达式?

我正在尝试创建一个通用函数,它可以使用任何正则表达式,并在用户输入无法满足表达式的内容时抛出异常。我们的表达式在宏观方案中相当简单,我们当然不会尝试解析HTML:)

提前致谢。 大卫

3 个答案:

答案 0 :(得分:1)

你只能通过使正则表达式的每个部分都可选,并重复自己来做到这一点:

^([EW]|[EW]\d{1,3}|[EW]\d{1,3}\.|[EW]\d{1,3}\.\d)$

这可能适用于简单的表达式,但对于复杂的表达式,这几乎不可行。

答案 1 :(得分:0)

很难说...如果用户键入“E”,则匹配开头但不匹配其余部分。当然,您不知道他们是否会继续输入“123.4”,或者他们是否会立即点击“Enter”(我假设您使用“Enter”来表示输入的结束)。您可以使用组来测试所有3个组是否匹配,例如:

([EW])(\d{1,3})(\.\d)

在第一个字符后,尝试匹配第一个字符。在接下来的几个输入之后,匹配第一个和第二个组,并在它们输入'。'时最后一个数字你必须找到所有3组的匹配。

答案 2 :(得分:0)

如果你的正则表达式lib支持它,你可以使用部分匹配(就像Boost.Regex一样)。

this page上的is_possible_card_number示例修改为您问题中的示例:

#include <boost/regex.hpp>


// Return false for partial match, true for full match, or throw for
// impossible match
bool
CheckPartialMatch(const std::string& Input, const boost::regex& Regex)
{
boost::match_results<std::string::const_iterator> what;
if(0 == boost::regex_match(Input, what, Regex, boost::match_default | boost::match_partial))
{
    // the input so far could not possibly be valid so reject it:
    throw std::runtime_error(
        "Invalid data entered - this could not possibly be a match");
}

// OK so far so good, but have we finished?
if(what[0].matched)
{
    // excellent, we have a result:
    return true;
}

// what we have so far is only a partial match...
return false;
}




int main() 
{
    const boost::regex r("[EW]\\d{1,3}\\.\\d");

    // The input is incomplete, so we expect a "false" result
    assert(!CheckPartialMatch("E1", r));

    // The input completely satisfies the expression, so expect a "true" result
    assert(CheckPartialMatch("E123.4", r));

    try{
        // Input can't match the expression, so expect an exception.
        CheckPartialMatch("EX3", r);
        assert(false);
    }
    catch(const std::runtime_error&){
    }

    return 0;
}