正则表达式:只有在没有特殊字符/内部注释的情况下才匹配模式

时间:2013-11-07 10:26:24

标签: php regex pcre regex-lookarounds

我输入的内容与以下示例类似,只需要替换所有\input{.*}命令,这些命令在行上的某个地方以 开头,前面有%

输入是LaTeX代码,其中%正在开始评论。这意味着当前行上%之后的所有内容都不应被解释为实际代码,实际上只是注释。 (即使它看起来像代码)

示例输入:

this is \input{REAL.tex} real content % just a \input{COMMENT.tex}
foo \input{REAL.tex} bar
\input{REAL.tex}
%\input{COMMENT.tex}
\input{REAL.tex} % comment

我目前的代码:

$r = "/^(?P<prefix>(?!.*%).*)\\\\input[{\s]+(?P<filename>.*?)[\s}](?P<suffix>.*)$/m";
$data = preg_replace($r, "REPLACED", $data);
echo $data . PHP_EOL;

CURRENT 示例输出:

this is \input{REAL.tex} real content % just a \input{COMMENT.tex}
foo REPLACED bar
REPLACED
%\input{COMMENT.tex}
\input{REAL.tex} % comment

预期示例输出:

this is REPLACED real content % just a \input{COMMENT.tex}
foo REPLACED bar
REPLACED
%\input{COMMENT.tex}
REPLACED % comment

问题:不幸的是,由于前瞻断言{{\inputs,我的正则表达式会完全忽略第一行和最后一行中的%。 1}}。

问题:您是否看到通过正则表达式实现所需输出的方法?第一行和最后一行的(?!.*%)也应该被替换。

2 个答案:

答案 0 :(得分:2)

你需要一个lookbehind来检查之前是否有%

/(?<=%).*?\\\\input\{.+?\}/mis

Lookbehind语法为(?<=(your regex)),因为它是负{4}}

集成在您的代码中,这看起来像

(?<!(your regex))

输出

$data = 'this is \input{REAL.tex} real content % just a \input{COMMENT.tex}
foo \input{REAL.tex} bar
\input{REAL.tex}
%\input{COMMENT.tex}
\input{REAL.tex} % comment';

$r = "/(?<!%)([^%]*)\\\\input\{.+?\}/";
$data = preg_replace($r, '$1REPLACED', $data);

echo $newData . PHP_EOL;

答案 1 :(得分:1)

我刚才意识到我不需要在这里使用外观!

代码:

$r = "/^(?P<prefix>[^%]*?)\\\\input\\{(?P<filename>[^}]*)\\}(?P<suffix>.*)$/m";
$data = preg_replace($r, "\\1REPLACED\\3", $data);
echo $data . PHP_EOL;

输出:

this is REPLACED real content % just a \input{COMMENT.tex}
foo REPLACED bar
REPLACED
%\input{COMMENT.tex}
REPLACED % comment