此正则表达式模式的更优雅(更短)的解决方案

More elegant (shorter) solution for this regex pattern

我花了三天时间思考如何找到一个单一的解决方案来匹配单引号或双引号与实际源字符串中转义的单引号或双引号之间的任何内容并替换匹配文本..我认为我已经成功了。多线或单线 - 它有效。也就是说,此正则表达式可用于 alter/change/sanitize 'text'"text" 或字符串,换句话说,在任何源代码中 *(例如:file_get_contents ('some_class.php'))并保留其他所有内容不受影响,假设代码注释在执行此类操作之前已被删除。

这是用单引号括起来的正则表达式..

'@"[^"\\]*(?:\\.[^"\\]*)*"|\'[^\'\\]*(?:\\.[^\'\\]*)*\'@msu'

.. 这里是用双引号括起来的正则表达式。

"@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|'[^'\\]*(?:\\.[^'\\]*)*'@msu"

像这样和源代码完美匹配...

// Very nasty php array 

$Damn = [

  'a' => "' lorem ipsum '",

  'b' => '"\" ipsu\'m lorem  ',

  'c' => " \' YabadabaDooya \" ",

  'd\"' => ' 

     f"

     o\'"o  

                 \'bar" ',

  'e' => "'",

  "f" => '"'

];

因为这是按我的预期工作的,而且我实际上不是 PCRE 大师(不要问我在过去三天里有多少 'pain' D:直到我想到这个解决方案),如果有人知道怎么做,并且愿意通过将上述正则表达式缩小为更多 elegant/shorter 解决方案来提供帮助,那就太好了。我假设模式中间的 | (or) 可以放在开头,只有一次 .. 我试过 上帝只知道什么 .. 来完成它,但运气不好。

所以,一般的问题是 - 上述模式的较短变体看起来如何相似?

这是我对此 problem/topic 的最终(这次,真的)回答。在我之前的 post(我删除了)中,我写了来自 Wahyu 的答案是完美的,但由于我天生缺乏耐心,这并不完全正确(没有“太多的测试”),因为进一步的测试显示出一些不准确。无论如何,我仍然声称 Wahyu 的方法 - IS - 是我一直在寻找的方法,只需一点点修改,这次我就成功了。

这是 Wahyu 的原始建议,它节省了我的时间 - 很多!

<<<REGEX

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


REGEX;

但是这个正则表达式失败了...

    
  $ArrayWithCorrectSyntaxButIdioticStrings = [
    

    'a' => 'C:\',

    'b' => "D:\",
    
    'c' => " This i\s '
      '
      \'
      ' not a 
      ' 
      \" love song"
    

  ];

它在 'a' 和 'b' => 值上都失败了,意思是 -> '\'

但是,只要稍微修改一下,它就真的变成了 - CHARM。

这里是黄金表达:)

  • Literal Variant(用于在线测试等)没有任何转义。
<<<REGEX

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

REGEX;

^^ 对于 regex101.com 测试 gmus 修饰符是必需的。

  • 还有一个可以安全投入生产的简单字符串变体:

    $regex = '@(["\'`])((?:\\.[\1]*|(?:(?!\1)).)*)(\1)@usm';

这是我自己的主要解决方案,它也可以正常工作,甚至可能性能更高,但我觉得它像 bI4tch 一样丑陋。 D:

    $regex = '@"[^"\\]*(?:\\.[^"\\]*)*"'
        . '|\'[^\'\\]*(?:\\.[^\'\\]*)*\''
        . '|`[^`\\]*(?:\\.[^`\\]*)*`'
        . '@usm';

总结一切...

两个正则表达式都将一次性找到并匹配反引号(php shell 执行)、单引号和双引号内的任何文本。

测试了超过 15 个超过 2000 或 3000 行代码的文件(在带有 PHP 8.1 built-in 网络服务器的 Debian 10 上)。

非常适合在对字符串使用单引号、双引号或反引号的任何源代码文件上提取或修改字符串 values/commands。

主要区别在于 Wahyu 的建议只能在一个地方(第一个捕获组)进行调整,而我的解决方案需要更多调整。


编辑:

一段时间后 and/or 同时,似乎没有必要寻找更多解决方案,因为存在三个有效变体,并且 sln 的适当答案已被接受,此问题不再属于讨论范畴。

对于 Spooky,试试这个 Multi-Delimiter 通用核心方法
这主要是你的正则表达式。

<<<PCRE

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

PCRE;

https://regex101.com/r/LLWa6L/1

<<<PCRE_EXPLAINED

     ( ["'`] )              # (1), The delimiters
     (                      # (2 start)
        (?:
           \ .                   # Escape anything
         |                       # or,
           (?!  | \ )          # Not a delimiter nor an escape
           .                      # Any character
        )*
     )                      # (2 end)
     (  )                 # (3), Backreference to the delimiter

PCRE_EXPLAINED;