【问题标题】:Regexp to match "foo/bar" and not "foobar" wanted正则表达式匹配“foo/bar”而不是“foobar”
【发布时间】:2012-04-07 17:59:09
【问题描述】:

我正在寻找一个正则表达式,我可以在我的标记器中使用它来编译配置文件。这是 php 中的一个类的 sn-p:

private $token = array(
    "PATH" => "([a-zA-Z\_-]+\.|\*\.)+([a-zA-Z\_-]+|\*)",
    "MIXED" => "[a-zA-Z0-9-_\(\)\/]{2,}",
    "STRING" => "[a-zA-Z-_]{2,}"
);

private function getToken($string) {
    foreach($this->token as $name => $pattern) {
        preg_match("/^".$pattern."/", $string, $match);
        if(!empty($match))
            return array($name, $match[0]);
    }

    return false;
}

“MIXED”应该匹配“foo/bar”而不是“foobar”,“STRING”应该匹配“foobar”而不是“foo/bar”。目前“foobar”和“foo/bar”是“混合”的。

我如何在一个模式中写下这个“AND NOT”?

谢谢。

【问题讨论】:

  • "混合" => "[a-zA-Z0-9-_()]+\/[a-zA-Z0-9-_()]+"
  • 更准确地说:“MIXED”也是“foo()”、“foo(255)”
  • 美洲狮走在正确的道路上。您想要表达的想法是“至少包含一个斜线”。
  • 哪种解析策略?第一场比赛?最大的匹配?
  • 第一场比赛。至少是一个“字符”。

标签: php regex


【解决方案1】:

此模式将匹配包含至少一个斜杠的任何字母、数字、下划线、连字符和斜杠序列:

[a-zA-Z0-9-_/]*\/[a-zA-Z0-9-_/]*

因此,这让您大致了解如何在匹配 ab/c 时拒绝像 abc 这样的令牌。这与区分浮点常量和整数常量非常相似。

您可能应该将foo/bar(255) 之类的输入标记为四个标记:foo/bar ( 255)

否则执行此斜线要求很复杂。天真的方式意味着MIXED 可以是这样的:

foo(255/255)
foo(/)

甚至:

)/-

只是因为它在某处包含斜线,不一定在您想要的位置。

阐明您的要求。

【讨论】:

  • 谢谢!这为我做到了:[a-zA-Z\"]*[\(\)\/\"][a-zA-Z0-9-_\(\)\'$%\"\.:\,\;\_\-\+\/<>#\?\s]* 现在我可以将这样的东西标记化:field.type = smallint(5) unsignedPATH EQUAL MIXED
  • ()[] 内部没有特殊含义,不需要斜线转义。对于您在其中逃脱的许多其他人来说也是如此,请参阅pcre.org/pcre.txt
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多