我需要某种正则表达式来获取花括号内的部分代码。还有其他问题,但我的有点不同。
将此代码视为示例;
public function my_method($my_input) {
if(true == false) { $me = "Forever alone. :("; }
if(true == true) { $me = "No longer alone. :}"; }
if(false == false) { $me = ":{ - This is so Wrong."; }
}
并忽略“公共函数my_method($ my_input)”部分。我该怎么抓
if(true == false) { $me = "Forever alone. :("; }
if(true == true) { $me = "No longer alone. :}"; }
if(false == false) { $me = ":{ - This is so Wrong."; }
没有被字符串中的“{”和“}”字符(和c的评论等)误导?
我对正则表达式的了解非常有限,而且我很难实现这一点。 :/
答案 0 :(得分:4)
匹配括号是您不应该尝试使用正则表达式的原型示例之一(即使没有括号内的正则表达式,它也太复杂了)。
这是因为具有嵌套括号的(正式)语言不是常规的,而是由无上下文的语法表示,比简单的正则表达式复杂得多。在非常高的层次上,正则表达式“不能计算到任意大数”,即它们无法识别哪个右括号属于哪个左括号(只要你允许任意嵌套括号的深度 - 比如PHP(至少在原则上) ))。
你应该更好地使用一些支持无上下文语法的工具,甚至可以获得一些已经编写过的PHP解析器。
为了自己提取函数,您应该只查找关键字function
(或指示功能块的其他关键字),然后转到左括号({{1 }})。然后,您可以逐个字符地继续,直到找到匹配的右括号({
),同时跟踪您当前是否在字符串或注释之内。
但是,我不希望你自己亲自完成这项任务,因为我可以想象,处理所有可能的角落案件会非常麻烦......
答案 1 :(得分:3)
我制作的正则表达式将在大多数情况下通过,即使引号被反斜杠。这是一个示例脚本。我在正则表达式中提供了注释,但请注意我需要在正则表达式中反斜杠,因为我将它用作正则表达式本身的字符串分隔符。
正则表达式是递归的,因此对括号嵌套的深度级数没有限制。但是,括号中不能有错误(即没有匹配的括号),但这是合乎逻辑的猜测。
$str =
'
public function my_method($my_input) {
if(true == false) { $me = "Forever alone. :("; }
if(true == true) { $me = "No longer alone. :}"; }
if(true == true) { $me = \'No longer alone. :}\'; }
if(true == true) { $me = \'No longer \\\' alone. :}\'; }
if(false == false) { $me = ":{ - This is so Wrong."; }
}
public function my_method($my_input) {
if(true == false) { $me = "Forever happy. :("; }
if(true == true) { $me = "No longer happy. :}"; }
if(true == true) { $me = \'No longer happy. :}\'; }
if(true == true) { $me = \'No longer \\\' happy. :}\'; }
if(false == false) { $me = ":{ - This is so Wrong."; }
}
';
preg_match_all(
'/
{ # opening {
( # matching parentheses
(?: # non matching parentheses
(?: # non matching parentheses
[^{}"\']+ # anything but { } " and \'
| # or
" # opening "
(?: # non matching parentheses
[^"\\\]* # anything but " and \
| # or
\\\" # a \ followed by a "
)* # as often as possible
" # closing "
| # or
\' # opening \'
(?: # non matching parentheses
[^\'\\\\]* # anything but \' and \
| # or
\\\\\' # a \ followed by a \'
)* # as often as possible
\' # closing \'
)* # as often as possible
| # or
(?R) # repeat the whole pattern
)* # as often as possible
) # close matching parentheses
} # closing }
/xs',
$str,
$matches
);
print_r($matches);
答案 2 :(得分:2)
正则表达式不是正确的工具 - 有关更多详细信息,请参阅@phimuemue's answer。
您可以在脚本中使用PHP's own tokenizer。但是,它不会简单地给你“一些块内的内容”,而是块内的令牌。根据您的要求,您需要从令牌重建源代码。