Получение переменных из строки с помощью регулярных выражений - PullRequest
2 голосов
/ 17 мая 2011

Я схожу с ума от регулярного выражения. У меня есть такая строка:

%closed% closed (%closed_percent%\%), %open% open (%open_percent%\%)

Мне нужно регулярное выражение, соответствующее следующему:

%closed%
%closed_percent%
%open%
%open_percent%

но не два \%

На данный момент я использую:

\%([^\%]+)\%

что дает мне:

%closed%
%closed_percent%
%), %
% open (%
...

Кто-нибудь может мне помочь с этим?

Ответы [ 5 ]

2 голосов
/ 17 мая 2011

Простой способ:

%\w+%

Совпадения: %foo%

Разрешает (множественные) обратные слэши:

(?<!\\)(?:\\.)*%(\w+)%

Только совпадения bar in: \%foo% \\%bar% \\\%baz%

... и это позволяет убегать внутри него:

(?<!\\)(?:\\.)*%((?:[^\\%\s]+|\\.)+)%

Совпадения: %foo\%bar%

Использовать значение первой группы захвата с двумя последними выражениями.

1 голос
/ 17 мая 2011

При условии отсутствия ограничений на то, что может быть в процентах обернутых токенов (включая экранированные символы) и какие символы могут быть экранированы (таким образом, экранирование также может быть экранировано: \\%token% должно быть допустимым),
вот шаблон, который вы можете использовать, чтобы пропустить экранированные символы:

\\.|(%([^%\\]|\\.)+%)

Это позволит получить токены в процентах и ​​в первой группе ($1). Экранированные символы также будут сопоставлены (это хороший способ пропустить их), но с помощью PHP очень просто получить только соответствующие токены:

preg_match_all('/\\\\.|(%([^%\\\\]|\\\\.)+%)/', $str, $matches, PREG_PATTERN_ORDER);
$matches = array_filter($matches[1]);

Рабочий пример: http://ideone.com/dziCB

1 голос
/ 17 мая 2011

Попробуйте:

\%([^(\\\%)]+?)\%

соответствует

%closed%
%closed_percent%
%open%
%open_percent%

для меня.

0 голосов
/ 17 мая 2011

Добавьте отрицательные взгляды для обратной косой черты! Таким образом, \% игнорируется, как и предполагалось.

(?<!\\)\%([^\%]+)(?<!\\)\%

Матчи

% закрыто%

% closed_percent%

% открыть%

% open_percent%

0 голосов
/ 17 мая 2011

Попробуйте:

~\%\w+\%~

Итак, разрешите только a-z A-Z и _ в вашем выборе.

$str = "%closed% closed (%closed_percent%\%), %open% open (%open_percent%\%)";

preg_match_all("~\%\w+\%~", $str, $matches);

$matches теперь содержит:

Array
(
    [0] => Array
    (
        [0] => %closed%
        [1] => %closed_percent%
        [2] => %open%
        [3] => %open_percent%
    )
)
...