2015-01-14 2 views
3

Я использую функцию __() для перевода строки, и я добавил интерфейс, чтобы автоматически находить все переводы тезисов во всех файлах. Это (предполагается) сделать с помощью следующего регулярного выражения:catching __ ('<string>') внутри простой и двойной цитаты

<?php 
$pattern = <<<'LOD' 
` 
    __\(
    (?<quote>    # GET THE QUOTE 
    (?<simplequote>')  # catch the opening simple quote 
    | 
    (?<doublequote>")  # catch the opening double quote 
    ) 
    (?<param1>    # the string will be saved in param1 
     (?(?=\k{simplequote}) # if condition "simplequote" is ok 
     (\\'|"|[^'"])+  # allow escaped simple quotes or anything else 
     |     # 
     (\\"|'|[^'"])+  # allow escaped double quotes or anything else 
    ) 
    ) 
    \k{quote}    # find the closing quote 
    (?:,.*){0,1}   # catch any type of 2nd parameter 
    \) 
    # modifiers: 
    # x to allow comments :) 
    # m for multiline, 
    # s for dotall 
    # U for ungreedy 
`smUx 
LOD; 
$files = array('/path/to/file1',); 
foreach($files as $filepath) 
{ 
    $content = file_get_contents($filepath); 
    if (preg_match_all($pattern, $content, $matches)) 
    { 
    foreach($matches['param1'] as $found) 
    { 
     // do things 
    } 
    } 
} 

, что регулярное выражение не работает для некоторых строки в двойных кавычках, содержащие сбежавшего простую цитату (\'). Кажется, что независимо от того, какая строка проста или двойна, условие считается ложным, поэтому всегда используется «else».

<?php 
// content of '/path/to/file1' 
echo __('simple quoted: I don\'t "see" what is wrong'); // do not work. 
echo __("double quoted: I don't \"see\" what is wrong");// works. 

для file1, я ожидаю, чтобы обе строки поиска, но только в двойных кавычках работы

Редактировать добавил еще PHP код, чтобы сделать его проще тестировать

+1

могли бы вы опубликовать некоторые действительными и недопустимые примеры вместе с ожидаемым результатом? –

+0

Посмотрите на http://stackoverflow.com/questions/6243778/split-string-by-delimiter-but-not-if-it-is-escaped. Главный ответ дает пример того, как захватывать экранированные последовательности. – eisberg

+0

Я только что отредактировал @AvinashRaj. Надеюсь, этого достаточно – Asenar

ответ

3

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

__\((['"])((?:\\\1|(?!\1).)*)\1\) 

DEMO

Объяснение:

  • __\( Матчи буквенные __( символов.

  • (['"]) Снимает следующие двойные или одинарные кавычки.

  • (?:\\\1|(?!\1).)* Матчи уцелевших двойные или одиночные кавычки (котировки на основе символов внутри индекса группы 1) или | не персонажа настоящего внутри группы захвата (?!\1). ноль или более раз.

  • \1 относится к персонажу в первой захваченной группе.

+0

Спасибо за объяснение. Это работает на демо, но не в моем коде ... пытается выяснить, почему – Asenar

+0

Это хорошее регулярное выражение +1 – anubhava

+0

очень хорошая идея! –

0
решение

Авинаша Raj является более элегантным и, вероятно, более эффективным (так что я проверить его), но я только что нашел свою ошибку, поэтому я выкладываю решение здесь:

<?php 
$pattern = <<<'LOD' 
` 
    __\(
    (?<quote>    # GET THE QUOTE 
    (?<simplequote>')  # catch the opening simple quote 
    | 
    (?<doublequote>")  # catch the opening double quote 
    ) 
    (?<param1>    # the string will be saved in param1 
     (?(simplequote)  # if condition "simplequote" 
     (\\'|[^'])+   # allow escaped simple quotes or anything else 
     |     # 
     (\\"|[^"])+   # allow escaped double quotes or anything else 
    ) 
    ) 
    \k{quote}    # find the closing quote 
    (?:,.*){0,1}   # catch any type of 2nd parameter 
    \) 
    # modifiers: 
    # x to allow comments :) 
    # m for multiline, 
    # s for dotall 
    # U for ungreedy 
`smUx 
LOD; 
Смежные вопросы