我需要找到所有出现的WP-Plugin标签。
<wpg3>10|300|defaultTemplate|eyJhbGlnbiI6ImFsaWdubGVmdCJ9</wpg3>
有标签的可能版本(,,, ...)但是开始和结束匹配。这些组是可选的:应该表示可以没有或者一个,或两个或三个“|”,它们将选项分开。
我的问题:如果我的搜索字符串中只有一个标记,一切都会按预期工作。 但是如果我在我的字符串中添加第二个标记,则回调只调用一次,而不是每个标记调用一次。在开始或结束时必须缺少某些东西。 如果缺少最后一个参数(功能),则Regexp无法使用多个标记。
$return = preg_replace_callback('/<wpg[23](?P<unused>id)?>(?P<uri_or_id>[^\|]*)[\|]?(?P<width>[^\|]*)[\|]?(?P<template>[^\|]*)[\|]?(?P<features>[^\|]*)<\/wpg[23](?P<unused2>id)?>/i', array( $this, 'wpg3_content' ), $content );
我采取上面的例子,我想得到:
Array
(
[0] => 10|300|defaultTemplate|eyJhbGlnbiI6ImFsaWdubGVmdCJ9
[unused] =>
[1] =>
[uri_or_id] => 10
[2] => 10
[width] => 300
[3] => 300
[template] => defaultTemplate
[4] => defaultTemplate
[features] => eyJhbGlnbiI6ImFsaWdubGVmdCJ9
[5] => eyJhbGlnbiI6ImFsaWdubGVmdCJ9
)
答案 0 :(得分:0)
一旦你回答了我上面的评论,我可能会有更精确的话。这是我到目前为止所拥有的。我用Python制作它因为它对我来说更容易,但你明白了。
这是我的正则表达式:
regex = re.compile('''
<(?P<tag>wpg[23])(?P<unused>id)?>
(?:
(?P<uri_or_id>[^\|<]+)
(?:
\|(?P<width>[^\|<]+)
(?:
\|(?P<template>[^\|<]+)
(?:
\|(?P<features>[^\|<]+)
)?
)?
)?
)?</(?P=tag)(?P<unused2>id)?>''', re.IGNORECASE|re.VERBOSE)
选项中的每个文本都是必填项,但可选的不匹配组确保选项确实是可选的。我还使用了一个后视表达式(?P=tag)
来确保结束标记与开始标记匹配。我使用[^\|]
保护匹配的内容略高于[^\|>]
,以防止出现多标记问题。
我的测试字符串:
# Your example
>>> text
'<wpg3>10|300|defaultTemplate|eyJhbGlnbiI6ImFsaWdubGVmdCJ9</wpg3>'
# Options should be, well, optional
>>> text2
'<wpg3>10|300|defaultTemplate</wpg3>'
# These two should fail if I understood properly
>>> text3
'<wpg3>10|300|defaultTemplate|</wpg3>'
>>> text4
'<wpg3>10|300||</wpg3>'
# Now with more than one tag
>>> text5
'<wpg3>10|300|defaultTemplate|eyJhbGlnbiI6ImFsaWdubGVmdCJ9</wpg3><wpg3>25|35|hello|world</wpg3>'
>>> text6
'<wpg3>10|300|defaultTemplate|eyJhbGlnbiI6ImFsaWdubGVmdCJ9</wpg3><wpg2>25|35|hello|world</wpg2>'
# This should fail because tags mismatch
>>> text7
'<wpg3>10|300|defaultTemplate|eyJhbGlnbiI6ImFsaWdubGVmdCJ9</wpg2>'
以下是测试:
# Parses as expected
>>> regex.match(text).groups()
('wpg3', None, '10', '300', 'defaultTemplate', 'eyJhbGlnbiI6ImFsaWdubGVmdCJ9', None)
>>> regex.match(text2).groups()
('wpg3', None, '10', '300', 'defaultTemplate', None, None)
# These two fail as expected
>>> regex.match(text3)
>>> regex.match(text4)
# Multi-tags now
>>> for m in regex.finditer(text5):
... m.groups()
...
('wpg3', None, '10', '300', 'defaultTemplate', 'eyJhbGlnbiI6ImFsaWdubGVmdCJ9', None)
('wpg3', None, '25', '35', 'hello', 'world', None)
>>> for m in regex.finditer(text6):
... m.groups()
...
('wpg3', None, '10', '300', 'defaultTemplate', 'eyJhbGlnbiI6ImFsaWdubGVmdCJ9', None)
('wpg2', None, '25', '35', 'hello', 'world', None)
# The last one fails (tag mismatch)
>>> regex.match(text7)
这是否符合您的需求?
答案 1 :(得分:0)
首先可以在标签上进行preg_match_all
preg_match_all("/<([^>]*)?>/",$in, $out);
然后遍历$ out数组,在那里你应该有标签名称和内容。
如果标签符合您的要求
explode($out[2],"|")
或者您是否希望在正则表达式中执行所有操作?