可以使用单个正则表达式完成此操作

时间:2013-10-09 17:22:45

标签: php regex

我有一系列字符串:

{ method_name { $key1 = 'quoted value' , $key2 = __('literal value'); }}

// Missing method_name and final semi-colon
// Still valid
{{ $key1 = 'quoted value' , $key2 = __('literal value') }}

// Optional key values
{ method_name { $key1 = , $key2 = __('literal value'); }}
{ method_name { $key1, $key2 = __('literal value'); }}

// Any number of values
{ method_name { $key1 = 'quoted value' , $keyN = 3.14; }}

目前,我使用了一系列preg_splittrim。这是自定义模板引擎的一部分,其中method_name通知解析器调用哪个方法,$key = value将作为数组传递给方法。这些字符串嵌入在HTML模板中,并且可以重复DOM结构。可以将其视为一个表,每个行/列具有不同的值。键是列详细信息(名称,可排序等),方法将填写单元格的详细信息。

我遇到的问题是速度。

Q1。我怎么能用一个表达式做到这一点?

Q2。我会获得任何速度吗?

Q3。如果我缓存了结果,那么可读性是否优于某种复杂的正则表达式?

Q4。有什么方法可以重构字符串以提升性能吗?

理想情况下,我只想扫描字符串一次,将其转换为PHP代码,并在每次需要使用时执行eval

2 个答案:

答案 0 :(得分:1)

我可能会使用这样的正则表达式(我在评论中发现了一些简化部分):

(?:\{ (?:(?<method>.+?)\s+\{)?|\G)[,\s]*(?<key>\$\w+)(?: = (?<value>[^,\n;}]*))?

指定的捕获组是不言自明的,但这是一个细分:

(?:
    \{ 
    (?:
        (?<method>.+?)   # Captures everything until the next { for the method
        \s+\{       
    )?                   # All this optional
    |
    \G                   # Or \G anchor, which will allow successive match of multiple key/value pairs
)
[,\s]*                   # Any spaces and commas
(?<key>\$\w+)            # Capture of key with format $\w+
(?: = 
    (?<value>[^,\n;}]*)  # Capture of value
)?                       # All this optional

regex101 demo

答案 1 :(得分:0)

您的表现问题可能会被误导。您似乎认为您的正则表达式匹配需要很长时间。据推测,你所拥有的课程花费的时间比你想要的要长。

不要优化正则表达式,除非您发现它们实际上是速度问题的原因。要了解是否属于这种情况,您需要使用XDebug之类的代码分析器来分析您的程序并创建一个报告,告诉您哪些内容很慢。

您可能会发现您的程序需要20秒才能运行,而在那段时间内,正则数据库需要花费2秒钟。即使将正则表达式匹配的执行时间减半,也只能节省1秒或5%的运行时间。

在不知道代码的哪一部分花费最多时间的情况下尝试加速代码是不成熟的优化。