基本上,我需要一个正则表达式来匹配PHP标记内的所有双引号字符串,而内部没有变量。
这是我到目前为止的内容:
"([^\$
]*?)"(?![\w ]*')
并替换为:
'$1'
但是,这也将匹配PHP标记之外的内容,例如HTML属性。
示例案例:
Here's my"dog's website"
$somevar ="someval";
$somevar2 ="someval's got a quote inside";
?>
$somevar3 ="someval with a $var inside";
$somevar4 ="someval" . $var . 'with concatenated' . $variables ."inside";
$somevar5 ="this php tag doesn't close, as it's the end of the file...";
它应该匹配并替换所有用'替换"的位置,这意味着html属性最好单独放置。
替换后的示例输出:
Here's my"dog's website"
$somevar = 'someval';
$somevar2 = 'someval\'s got a quote inside';
?>
$somevar3 ="someval with a $var inside";
$somevar4 = 'someval ' . $var . 'with concatenated' . $variables . 'inside';
$somevar5 = 'this php tag doesn\'t close, as it\'s the end of the file...';
同样也可以在脚本标签内进行匹配...但这可能会推动它进行一次正则表达式替换。
我需要一个正则表达式方法,而不是PHP方法。 假设我在文本编辑器或JavaScript中使用regex-replace来清理PHP源代码。
使用preg_replace_callback()匹配php标签,并在回调中使用您的正则表达式。
@HamZa如果php中有这样的东西:$a = ;怎么办?
@ hek2mgl您能告诉我在一般情况下发生这种情况的机会吗?
@HamZa机会相对较高。至少如果有人检测到并想要利用它。解析和处理源代码需要有状态的解析器。使用tokenizer扩展可能是一个起点。
好吧,这里有两种选择:冒险或很难使用完整的解析器。
@HamZa检查我的答案。 tokenizer做得很好。我认为该功能是解决该问题的合理方法,因为任何简单的正则表达式解决方案的问题都会导致源文件损坏。
两者都谢谢,但我的问题应该更清楚一些,我需要基于正则表达式的方法而不是基于php的方法(不是特定于语言)
@ HarryMustoe-Playfair您必须非常准确。如果需要正则表达式解决方案,则必须提供要使用的正则表达式风格。由于正则表达式可能因语言/环境而异。例如,JavaScript不支持lookbehinds (?。 IMO在几乎没有回调的情况下几乎不可能替换单个正则表达式中的内容。
嗯,那真是太可惜了,我想那时我不得不依靠别的东西。我的字面意思是我可以在文本编辑器中用正则表达式替换或者用正则表达式替换javscript以便我可以创建一个方便的jsfiddle来清理一些php的东西。
正则表达式可能不是您要解决的那种问题的解决方案。他们只是不打算处理太多的复杂性。您确实需要使用能够理解该语言的构造。
@vks是的,基本上使用可接受的单引号字符串文字,否则使用双引号。
@Jon Surrell确实,我认为使用简单的正则表达式替换现在可能无法实现,而是需要某种解析器。
我认为那是您最好的行动方案。正则表达式在这方面是不好的。
@ HarryMustoe-Playfair使用JavaScript的正则表达式味道是一个可怕的笑话,因为它是最差的正则表达式引擎之一。另外,文本编辑器具有不同的正则表达式引擎,您打算使用哪一个?
@ DJDavid98指出答案"不正确"本身就是错误的。它以正确和安全的方式完成工作。另请参阅编辑历史记录,也难怪此线程有点混乱。
TL;博士
正则表达式确实太复杂了。尤其不是简单的正则表达式。嵌套正则表达式可能会更好,但是您确实需要进行词法分析/语法分析才能找到字符串,然后可以使用正则表达式对它们进行操作。
说明
您可能可以做到这一点。
您甚至可能甚至可以完美地做到这一点。
但这并不容易。
这将非常非常困难。
考虑一下:
Welcome to my php file. We're not"in" yet.
/* Ok. now we're"in" php. */
echo"this is "stringa"";
$string = 'this is "stringb"';
echo"$string";
echo"\$string";
echo"this is still ?> php.";
/* This is also still ?> php. */
?> We're back ="out"?> of php. <?php
// Here we are again,"in" php.
echo <<
How do"you" want to ""deal"" with this STRING;
STRING;
echo <<
Apparently this is \"Nowdoc\". I've never used it.
STRING;
echo"And what about \" ."this? Was that a tricky '"' to catch?";
// etc...
忘记用双引号引起来的匹配变量名。
您能否在此示例中匹配所有字符串?
在我看来,这就像一场噩梦。
SO的语法高亮当然不知道该怎么做。
您是否认为变量也可能出现在Heredoc字符串中?
我不想考虑正则表达式来检查:
内部或=代码
不在评论中
引号内
什么类型的报价?
它是那种类型的报价吗?
是否在\之前(转义)?
\是否已转义?
等等...
摘要
您可能可以为此编写一个正则表达式。
您可能可以通过一些反向引用以及大量的时间和精力来进行管理。
这将很困难,可能会浪费很多时间,并且,如果您需要修复它,那么您将不会理解您编写的正则表达式。
也可以看看
这个答案。这很值得。
这是一个利用tokenizer扩展将preg_replace仅应用于PHP字符串的函数:
function preg_replace_php_string($pattern, $replacement, $source) {
$replaced = '';
foreach (token_get_all($source) as $token) {
if (is_string($token)){
$replaced .= $token;
continue;
}
list($id, $text) = $token;
if ($id === T_CONSTANT_ENCAPSED_STRING) {
$replaced .= preg_replace($pattern, $replacement, $text);
} else {
$replaced .= $text;
}
}
return $replaced;
}
为了实现您想要的,可以这样称呼它:
$filepath ="script.php";
$file = file_get_contents($filepath);
$replaced = preg_replace_php_string('/^"([^$\{
<>\']+?)"$/', '\'$1\'', $file);
echo $replaced;
作为第一个参数传递的正则表达式是此处的关键。它告诉该函数仅在不包含$(嵌入变量"$a"),{(嵌入变量类型2 "{$a[0]}"),换行(HTML标记结束/打开符号)。它还检查字符串是否包含单引号,并防止替换,以避免需要转义的情况。
尽管这是一个PHP解决方案,但它是最准确的一种。使用其他任何语言所能获得的最接近的结果,都需要您在某种程度上以该语言构建自己的PHP解析器,以使解决方案准确无误。
这是一种有趣的方法,但是我恐怕无法为所需的功能使用PHP!
您将要使用哪种语言?