2013-08-04 50 views
3

的提取参数,我有以下的LaTeX命令:PHP preg_match_all:命令

\autocites[][]{}[][]{} 

其中内[]的参数都是可选的内部{}别人是强制性的。

\autocites[a1][a2]{a3}[b1][b2]{b3} 
\autocites[a1][a2]{a3}[b1][b2]{b3}[c1][c2]{c3} 
... 

它也可用于这样的::所述\autocites命令可以由等的参数附加组进行扩展

\autocites{a}{b} 
\autocites{a}[b1][]{b3} 
\autocites{a}[][b2]{b3} 
... 

我想通过使用PHP中的正则表达式来提取它的参数。这是我第一次尝试:

/\\autocites(\[(.*?)\])(\[(.*?)\])(\{(.*?)\})(\[(.*?)\])(\[(.*?)\])(\{(.*?)\})/ 

虽然如果\autocites只包含两组三个参数,我无法弄清楚如何得到它的未知数量的参数工作能正常工作。

我用下面的表达式也试过:

/\\autocites((\[(.*?)\]\[(.*?)\])?\{(.*?)\}){2,}/ 

这一次我能匹配更大的参数号码,但随后我不能提取所有的值,因为PHP永远只是给我的最后三个参数的内容:

Array 
(
    [0] => Array 
     (
      [0] => \autocites[a][b]{c}[d][e]{f}[a][a]{a} 
     ) 

    [1] => Array 
     (
      [0] => [a][a]{a} 
     ) 

    [2] => Array 
     (
      [0] => [a][a] 
     ) 

    [3] => Array 
     (
      [0] => a 
     ) 

    [4] => Array 
     (
      [0] => a 
     ) 

    [5] => Array 
     (
      [0] => a 
     ) 

) 

任何帮助,非常感谢。

+2

仅仅匹配包含随机'(\ {。\} | \ [。\])*'变体的整个命令可能会更简单。然后使用第二个'preg_match_all'来提取单个参数。或者使用'?(DEFINE)'或者至少'/ x'修饰符来创建一个可管理的正则表达式。 – mario

回答

2

你必须分两步做。只有.NET才能检索任意数量的捕获。在所有其他风格中,捕获结果的数量由您模式中的组数量决定(重复一组只会覆盖先前的捕获)。

因此,首先匹配整个事情得到的参数,然后在第二个步骤中提取它们:

preg_match('/\\\\autocites((?:\{[^}]*\}|\[[^]]*\])+)/', $input, $autocite); 
preg_match_all('/(?|\{([^}]*)\}|\[([^]]*)\])/', $autocite[1], $parameters); 
// $parameters[1] will now be an array of all parameters 

Workingdemo.

使用稍微复杂的方法和锚\G我们可以也可以通过使用任意数量的匹配而不是捕获来完成所有工作:

preg_match_all('/ 
    (?|    # two alternatives whose group numbers both begin at 1 
     \\\\autocites # match the command 
     (?|\{([^}]*)\}|\[([^]]*)\]) 
        # and a parameter in group 1 
    |    # OR 
     \G   # anchor the match to the end of the last match 
     (?|\{([^}]*)\}|\[([^]]*)\]) 
        # and match a parameter in group 1 
    ) 
    /x', 
    $input, 
    $parameters); 
// again, you'll have an array of parameters in $parameters[1] 

Working demo.

请注意,采用这种方法 - 如果代码中有多个autocites,您将在一个列表中获取所有命令中的所有参数。有一些方法可以缓解这种情况,但我认为在这种情况下第一种方法会更清晰。

如果您希望能够区分可选参数和强制参数(使用任何方法),请将参数的开头或结尾括号/括号与参数一起捕获,并检查该字符以确定它是哪种类型。

+2

在PHP中,'\\ a''是'\ a',为了得到''''你需要写''''''''。或者你可以使用'<<<'quoting''。 (我认为。):-p – Qtax

+0

@当然@ Qtax)...感谢您的注意。固定;) –

+0

工程就像一个魅力。太好了谢谢! – Mark