2

我有以下代码:

/* record 863.content.en */
UPDATE language_def
SET en='<html>blah blah markup</html>'
WHERE page_id=863,
AND string_id='content';
/* record_end 863.content.en */

我想创建一个表达式来匹配该语句,其中:

  1. 期间之间的数据863.content.en是可变的,但具体(连续会有许多这样的语句)
  2. 两条评论之间的数据是可变的,但不是特定的

这是我到目前为止所拥有的:

'[/*]\s*record\s*specific_number[.]specific_string1[.]specific_string2\s*[*/].*[/*]\s*record_end\s*specific_number[.]specific_string1[.]specific_string2\s*[*/]'
4

2 回答 2

0

您的正则表达式存在一些问题。

首先,正如 FrankeTheKneeMan 指出的那样,您需要分隔符。#是 HTML 匹配的好选择(标准选择是/,但它经常干扰标签):

'#[/*]\s*record\s*specific_number[.]specific_string1[.]specific_string2\s*[*/].*[/*]\s*record_end\s*specific_number[.]specific_string1[.]specific_string2\s*[*/]#'

现在虽然[.]是转义单个字符的好方法,但对于[/*]. 这是一个字符类,匹配/*。对[*/]. 改用这个:

'#/[*]\s*record\s*specific_number[.]specific_string1[.]specific_string2\s*[*]/.*/[*]\s*record_end\s*specific_number[.]specific_string1[.]specific_string2\s*[*]/#'

现在.*是剩下的问题。实际上也有,一个是关键的,另一个可能不是。第一个是.默认不匹配换行符。您可以使用s(singleline) 修饰符来更改它。第二个,*就是贪心。如果一个部分在字符串中出现两次,您将获得从第一个对应/* record到最后一个对应的所有内容/* record_end,即使两者之间存在不相关的内容。由于您的记录似乎非常具体,我想情况并非如此。但是,通常最好的做法是使量词不贪婪,以使其消耗尽可能少。这是您的最终正则表达式字符串:

'#/[*]\s*record\s*specific_number[.]specific_string1[.]specific_string2\s*[*]/.*?/[*]\s*record_end\s*specific_number[.]specific_string1[.]specific_string2\s*[*]/#s'

对于您提出的示例,这是

'#/[*]\s*record\s*863[.]content[.]en\s*[*]/.*?/[*]\s*record_end\s*863[.]content[.]en\s*[*]/#s'

如果你想找到所有这些部分,那么你可以 make863和variable 捕获它们(使用括号)contenten使用反向引用来确保你得到相应的record_end

'#/[*]\s*record\s*(\d+)[.](\w+)[.](\w+)\s*[*]/.*?/[*]\s*record_end\s*\1[.]\2[.]\3\s*[*]/#s'
于 2012-11-20T22:22:53.450 回答
0
'#/\* record (\S+) \*/.*<html>(.*)</html>.*/\* record_end \1 \*/#is'

此正则表达式会将您的字符串拆分为单独的记录,如此处所示。您可以随意用 替换任何空格\s*,但为了便于阅读,我将其保留为这种方式。 \S+匹配任意数量的非空白字符,但您可以根据需要将其替换为您的特定字符串。否则,您可以解析 preg_match_all 返回的匹配对象,并使用第一个子捕获来获取特定记录,并使用第二个子捕获来获取html标签之间的信息。#s 是 php 分隔正则表达式所需的分隔符 -不i区分大小写并s匹配.新行。

于 2012-11-20T22:23:12.763 回答