Как исключить символы из шаблона RegEx с кодами свойств категории?

Существует несколько кодов свойств категории (см. Часть "Свойства символов 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.

/Catalog/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,
                    ),
                )
            ),
        ),
    ),
    ...
);

2 ответа

Решение

Вы можете использовать отрицательный прогноз, чтобы исключить некоторые символы из вашего набора символов. Для вашего примера:

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

По сути, вы проверите, что следующий символ не / с негативным прогнозом (?!/)перед тем, как проверить, принадлежит ли этот символ к набору символов [\p{L}\p{N}\p{Zs}\p{P}],

PCRE не имеет функции пересечения или установки разности, так что это обходной путь для этого.

Так как вы используете его для разбора URL:

Согласно RFC 1738 только $-_.+!*'(), разрешены незашифрованные в URL¹, поэтому вместо использования \pP (да, это разрешено вместо \p{P}), Я предлагаю вам использовать эти символы непосредственно в вашем регулярном выражении.

Изменить: Но если это не вариант, это должно быть отправной точкой

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

С уважением, Том

¹: не совсем верно, но /@#;?&= разрешены в незашифрованном виде, только если они должны иметь свое особое значение.

Другие вопросы по тегам