我想从一个字符串从一个字符串中删除PHP标记与Python
content = re.sub('<\?php(.*)\?>', '', content)
删除PHP代码似乎工作的单行PHP标签OK,但是当一个PHP标签后关闭一些行,就不能抓住它。 任何人都可以帮忙吗?
我想从一个字符串从一个字符串中删除PHP标记与Python
content = re.sub('<\?php(.*)\?>', '', content)
删除PHP代码似乎工作的单行PHP标签OK,但是当一个PHP标签后关闭一些行,就不能抓住它。 任何人都可以帮忙吗?
如果你只是想处理简单的情况下,一个简单的正则表达式将正常工作。 Python正则表达式中的*?
运算符提供了最小匹配。
import re
_PHP_TAG = re.compile(r'<\?php.*?\?>', re.DOTALL)
def strip_php(content):
return _PHP_TAG.sub('', content)
INPUT = """
Simple: <?php echo $a ?>.
Two on one line: <?php echo $a ?>, <?php echo $b ?>.
Multiline: <?php
if ($a) {
echo $b;
}
?>.
"""
print strip_php(INPUT)
输出:
Simple: . Two on one line: (keep this) . Multiline: .
我希望你不使用这种净化输入,因为这是不是为此目的不够好。 (这是一个黑名单,而不是一个白名单和黑名单是远远不够的。)
如果要处理复杂的情况下,如:
<?php echo '?>' ?>
你仍然可以做它用正则表达式,但你不妨重新考虑你使用的是什么工具,因为正则表达式可能太复杂而无法阅读。下面的正则表达式将处理所有的弗朗西斯阿维拉的测试用例:
dstr = r'"(?:[^"\\]|\\.)*"'
sstr = r"'(?:[^'\\]|\\.)*'"
_PHP_TAG = re.compile(
r'''<\?[^"']*?(?:(?:%s|%s)[^"']*?)*(?:\?>|$)''' % (dstr, sstr)
)
def strip_php(content):
return _PHP_TAG.sub('', content)
正则表达式几乎强大到足以解决这个问题。我们知道这是因为PHP使用正则表达式来标记PHP源代码。您可以阅读PHP在Zend/zend_language_scanner.l
中使用的正则表达式。它是为Lex编写的,这是一个从正则表达式创建分词器的常用工具。
我说“几乎”的原因是因为我们实际上使用扩展正则表达式。
其在我的情况下工作,但没有're.DOTALL | re.MULTILINE' – wtayyeb 2012-04-24 02:18:45
你是对的,都不是必需的。我正在玩正则表达式时忘了带出它们。 – 2012-04-24 03:58:54
你可以做到这一点,通过这一点:
content = re.sub('\n','', content)
content = re.sub('<\?php(.*)\?>', '', content)
后OP的评论更新答案:
content = re.sub('\n',' {NEWLINE} ', content)
content = re.sub('<\?php(.*)\?>', '', content)
content = re.sub(' {NEWLINE} ','\n', content)
例如ipython
:
In [81]: content
Out[81]: ' 11111 <?php 222\n\n?> \n22222\nasd <?php asd\nasdasd\n?>\n3333\n'
In [82]: content = re.sub('\n',' {NEWLINE} ', content)
In [83]: content
Out[83]: ' 11111 <?php 222 {NEWLINE} {NEWLINE} ?> {NEWLINE} 22222 {NEWLINE} asd <?php asd {NEWLINE} asdasd {NEWLINE} ?> {NEWLINE} 3333 {NEWLINE} '
In [84]: content = re.sub('<\?php(.*)\?>', '', content)
In [85]: content
Out[85]: ' 11111 {NEWLINE} 3333 {NEWLINE} '
In [88]: content = re.sub(' {NEWLINE} ','\n', content)
In [89]: content
Out[89]: ' 11111 \n3333\n'
你解决不了这个问题,常用表达。从一个字符串解析PHP需要一个真正的解析器,它至少能够理解一点PHP。
但是,如果您有PHP可用,您可以很容易地解决这个问题。 PHP解决方案。
这里是你有多少种方法去错了你的正则表达式的方法演示:
import re
testcases = {
'easy':("""show this<?php echo 'NOT THIS'?>""",'show this'),
'multiple tags':("""<?php echo 'NOT THIS';?>show this, even though it's conditional<?php echo 'NOT THIS'?>""","show this, even though it's conditional"),
'omitted ?>':("""show this <?php echo 'NOT THIS';""", 'show this '),
'nested string':("""show this <?php echo '<?php echo "NOT THIS" ?>'?> show this""",'show this show this'),
'shorttags':("""show this <? echo 'NOT THIS SHORTTAG!'?> show this""",'show this show this'),
'echotags':("""<?php $TEST = "NOT THIS"?>show this <?=$TEST?> show this""",'show this show this'),
}
testfailstr = """
FAILED: %s
IN: %s
EXPECT: %s
GOT: %s
"""
removephp = re.compile(r'(?s)<\?php.*\?>')
for testname, (in_, expect) in testcases.items():
got = removephp.sub('',in_)
if expect!=got:
print testfailstr % tuple(map(repr, (testname, in_, expect, got)))
请注意,这是非常困难的,如果不是不可能得到一个正则表达式来通过所有的测试案例。
如果你有PHP可用,你可以使用PHP的tokenizer来去除PHP。以下代码应该去掉全部 PHP代码从字符串中排除不会失败,并且应该覆盖所有奇怪的角落案例。
// one-character token, always code
define('T_ONECHAR_TOKEN', 'T_ONECHAR_TOKEN');
function strip_php($input) {
$tokens = token_get_all($input);
$output = '';
$inphp = False;
foreach ($tokens as $token) {
if (is_string($token)) {
$token = array(T_ONECHAR_TOKEN, $token);
}
list($id, $str) = $token;
if (!$inphp) {
if ($id===T_OPEN_TAG or $id==T_OPEN_TAG_WITH_ECHO) {
$inphp = True;
} else {
$output .= $str;
}
} else {
if ($id===T_CLOSE_TAG) {
$inphp = False;
}
}
}
return $output;
}
$test = 'a <?php //NOT THIS?>show this<?php //NOT THIS';
echo strip_php($test);
我欣赏实际答案,旁边解释为什么正则表达式不足。尼斯。 – 2012-04-23 23:23:51
我发布了一个处理所有测试用例的正则表达式。我怀疑像大多数标记器一样,PHP标记器首先建立在正则表达式上。通过使用PHP标记器,您可以省去编写正则表达式的工作,但实际上仍然使用正则表达式。 – 2012-04-23 23:26:36
如果您好奇,可以阅读PHP在PHP源代码文件“Zend/zend_language_scanner.l”中使用的正则表达式。 – 2012-04-23 23:33:42
我认为这超出了正则表达式的能力,你需要一个实际的解析器。例如:'<?php echo''?>','<?php if(1):?> PHP ','<? echo'shorttags!'?>','=$echos?>'等 – 2012-04-23 21:20:45
@FrancisAvila刚删除将完成我的工作! – wtayyeb 2012-04-23 21:39:37
不,它不会。你认为它会,但它不会。试试这些测试用例的正则表达式。还要记住,你可以在php中省略最后的'?>'。 – 2012-04-23 21:44:35