0

有许多类别属性代码(参见“Unicode 字符属性”部分),可用于与Perl 兼容的正则表达式 (PCRE)

我定义了一个正则表达式模式(命名为 subpattern),它应该匹配字母 ( \p{L})、数字 ( \p{N})、空格分隔符 ( \p{Zs}),还有标点符号 ( \p{P})。

(?<sport>[\p{L}\p{N}\p{Zs}\p{P}]*)

由于我将其用于 URL 路由,因此应排除斜杠。我怎样才能做到这一点?


编辑:

关于上下文的附加信息:该模式用于 Zend Framework 2 模块中的路由定义。

/目录/config/module.config.php

<?php
return array(
    ...
    'router' => array(
        'routes' => array(
            ...
            'sport' => array(
                'type'  => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
                'options' => array(
                    'regex' => '/catalog/(?<city>[\p{L}\p{Zs}]*)/(?<sport>[\p{L}\p{N}\p{Zs}\p{P}]*)',
                    'defaults' => array(
                        'controller' => 'Catalog\Controller\Catalog',
                        'action'     => 'list-courses',
                    ),
                    'spec'  => '/catalog/%city%/%sport%',
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'courses' => array(
                    'type'  => 'segment',
                        'options' => array(
                            'route' => '[/page/:page]',
                            'defaults' => array(
                                'controller' => 'Catalog\Controller\Catalog',
                                'action'     => 'list-courses',
                            ),
                        ),
                        'may_terminate' => true,
                    ),
                )
            ),
        ),
    ),
    ...
);
4

2 回答 2

3

您可以使用否定前瞻从字符集中排除某些字符。对于您的示例:

(?<sport>(?:(?!/)[\p{L}\p{N}\p{Zs}\p{P}])*)

基本上,在继续检查该字符是否属于字符集之前,您将检查下一个字符是否/具有负前瞻(?!/)[\p{L}\p{N}\p{Zs}\p{P}]

PCRE 没有设置交集或设置差异功能,所以这是解决方法。

于 2013-04-26T15:32:37.097 回答
0

由于您将其用于 URL 解析:

根据RFC 1738 ,只$-_.+!*'(),允许在 URL 中未编码¹,因此我建议您直接在正则表达式中使用这些字符,而不是使用\pP(是的,允许使用而不是)。\p{P}

编辑:但如果这不是一个选项,这应该是一个起点

(?:([\p{L}\p{N}\p{Zs}\p{P}]+?)(?=/|\?|#|$))

亲切的问候,汤姆

¹:不完全正确,但/@#;?&=只有在它们应该具有特殊含义时才允许未编码。

于 2013-04-26T15:26:11.783 回答