【问题标题】:catching __('<string>') inside simple and double quote在简单和双引号内捕获 __('<string>')
【发布时间】:2015-03-12 19:21:04
【问题描述】:

我使用函数__() 翻译字符串,并添加了一个接口来自动查找所有文件中的所有论文翻译。这(应该是)使用以下正则表达式完成:

<?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 代码,以便于测试

【问题讨论】:

  • 您能否发布一些有效和无效的示例以及预期的输出?
  • 看看stackoverflow.com/questions/6243778/… 上面的答案提供了一个关于如何捕获转义序列的示例。
  • 我刚刚编辑了 @AvinashRaj 。我希望这就足够了

标签: php regex internationalization


【解决方案1】:

使用下面的正则表达式并从组索引 2 中获取您想要的字符串。

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

DEMO

说明:

  • __\( 匹配文字 __( 字符。

  • (['"]) 捕获以下双引号或单引号。

  • (?:\\\1|(?!\1).)* 匹配转义的双引号或单引号(引号基于组索引 1 内的字符)或 | 不是捕获组内的字符 @ 987654329@ 零次或多次。

  • \1 指的是第一个捕获组中的字符。

【讨论】:

  • 感谢您的解释。这适用于演示,但不适用于我的代码......试图找出原因
  • 你能给我解释一下吗:根据文档 (php.net/manual/fr/regexp.reference.assertions.php) 我理解 (?!\1).) 为“匹配任何东西(.),除非之前有引号”这应该是在引号后的第一个字符处附加。我错过了什么?
  • (?!\1). 表示匹配任何字符 . 但不匹配组索引 1 内的字符。如果组索引 1 包含双引号,(?!\1). 将匹配除双引号之外的任何字符。同样,对于单引号..
  • 好的,非常感谢!我刚刚理解了前瞻的东西,意思是“休息一下。现在,让我们看看下一个角色的样子……允许吗?好的,你可以继续”
【解决方案2】:

Avinash 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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多