求一个PHP正则表达解法

beshy 2011-11-23 01:33:56
上字符串:
asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>czxxc

求 <b=1>...</b> 内 所有 a的值组成得数组

现在我是两步实现:

<?php
$s = 'asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>czxxc';
preg_match('/<b=1>.*?<\/b>/', $s, $m);
preg_match_all('/<a=(\d)>/', $m[0],$v);
var_dump($v[1]); // a 所有的值
?>


输出:
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "3"
}

求仅用一次匹配出来.
...全文
331 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
beshy 2011-11-24
  • 打赏
  • 举报
回复
吃过早餐脑子好使点了...


<?php
$s = '
asd
<b=1>
a<c>b<d><b>das<a>
<a=1>
<c><d><b>
<a=2>
dsa</bb><<<s<<<>>>>>><<asd><a>,
<a=3><b=><//b>xcv
<a=4>xcv,..<><a=9
<a=a>
<a=5>xcv,<<a=123>
ddd<dsa></a>
</b>
vv
<b=2>asd<a=6>asdasd<a=7>dsa<a=8>ddd</b>czxxc';

$p = '/
(?:<b=1>|\G)
(?:
<(?!\/b>)[^<]*?
|
[^<]*?
)*?
<a=\K(\d)>/six';

preg_match_all($p,$s,$m);
print_r($m[1]);
/*
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
*/

成功匹配<b=1>...</b>中的<a=\d>.
正则真让人心力交瘁额...
谢谢各位大侠.
床上等您 2011-11-24
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 foolbirdflyfirst 的回复:]

引用 10 楼 yangball 的回复:

但很明显 (a=) 这个有很多层,我都 + 来表示其有重复的情况了

按我的想法,匹配到一个然后入栈,依次循环才对的。

因为括号里的才推如捕获组。
比如类似串如:abcd
那我们知道/(a)(b)(c)(d)/的捕获组是0=>abcd,1=>a,2=>b,3=>c,4=>d,因为有4个()
那么如果是/(\w)*/,捕获组很容易知……
[/Quote]
我的正则是
/<b=1>(?:\w*<a=(\d)>\w*)*<\/b>/
第一个 () 是非捕获
第二个是 捕获的(在非捕获里嵌套了)
非捕获的我己经让他进行多次循环匹配了。就是这里不明白
如果不循环,那获取结果只有最后一个(3)是无可否认。
beshy 2011-11-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 foolbirdflyfirst 的回复:]

试试
PHP code
$str = 'asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=4>asdasd<a=5>dsa<a=6>ddd</b>czxxc';
$pat……
[/Quote]

学习了~..

我改了下, 大脑又堵塞了...

字符串如果是

$s = '
asd
<b=1>
a<c>b<d><b>das<a>
<a=1>
<c><d><b>
<a=2>
dsa</bb>
<a=3>
ddd<dsa></a>
</b>
vv
<b=2>asd<a=4>asdasd<a=5>dsa<a=6>ddd</b>czxxc';


这个中间又有<>
依然求<b=1>...</b> 中间的<a=\d>值

一起混吧 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 foolbirdflyfirst 的回复:]

引用 21 楼 ohmygirl 的回复:

哈哈,看到foolbirdflyfirst
想起鸟哥linux私房菜。

弱弱地问一句:为啥都是bird?

纯属玩笑,莫见怪

比不了鸟哥大大,哥永远是菜鸟,这点毋庸置疑啊。
比如昨天折腾了一天才把android开发配置好,一个按下F2的就解决的问题搞了半天,真想把电脑砸了。
[/Quote]在研究android开发了啊。准备转行了?
foolbirdflyfirst 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 jordan102 的回复:]

引用 19 楼 foolbirdflyfirst 的回复:

引用 17 楼 jordan102 的回复:

引用 15 楼 foolbirdflyfirst 的回复:

sorry
==============================
那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>d
请教一下: 按理来说,从左至右,1应该是a呀。怎么会是d 呢?难……
[/Quote]
不是我学得好,学得好的应该是那些正则魔人,都研究什么有限状态自动鸡。
这个模式是之前为了解决某个问题碰巧发现的,算运气。
foolbirdflyfirst 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 ohmygirl 的回复:]

哈哈,看到foolbirdflyfirst
想起鸟哥linux私房菜。

弱弱地问一句:为啥都是bird?

纯属玩笑,莫见怪
[/Quote]
比不了鸟哥大大,哥永远是菜鸟,这点毋庸置疑啊。
比如昨天折腾了一天才把android开发配置好,一个按下F2的就解决的问题搞了半天,真想把电脑砸了。
ohmygirl 2011-11-23
  • 打赏
  • 举报
回复
哈哈,看到foolbirdflyfirst
想起鸟哥linux私房菜。

弱弱地问一句:为啥都是bird?

纯属玩笑,莫见怪
一起混吧 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 foolbirdflyfirst 的回复:]

引用 17 楼 jordan102 的回复:

引用 15 楼 foolbirdflyfirst 的回复:

sorry
==============================
那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>d
请教一下: 按理来说,从左至右,1应该是a呀。怎么会是d 呢?难道真是覆盖了?

是的。#13楼有提到
[/Quote]谢谢foolbirdflyfirst,正则学的这么好。。。
foolbirdflyfirst 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 jordan102 的回复:]

引用 15 楼 foolbirdflyfirst 的回复:

sorry
==============================
那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>d
请教一下: 按理来说,从左至右,1应该是a呀。怎么会是d 呢?难道真是覆盖了?
[/Quote]
是的。#13楼有提到
一起混吧 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 ohmygirl 的回复:]
另外jordan的写法也不完善,如果<a=\d>的数量多一个,那么可能就匹配不到了。
[/Quote]恩。那种方法是写死的。。数量一多就不行了。想要一次匹配到还得考虑其他方法或者跟楼主一样分两次来。
一起混吧 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 foolbirdflyfirst 的回复:]

sorry
==============================
那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>d
[/Quote]请教一下: 按理来说,从左至右,1应该是a呀。怎么会是d 呢?难道真是覆盖了?
foolbirdflyfirst 2011-11-23
  • 打赏
  • 举报
回复
如果你捕获到成千上万个字符,难道一个个都推入捕获组么?
=================================================
应该说成:如果你捕获到成千上万个字符,难道一个个都创建新的捕获组么?

抱歉,刚吃饱饭,脑子供氧不足。
foolbirdflyfirst 2011-11-23
  • 打赏
  • 举报
回复
sorry
==============================
那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>d
ohmygirl 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 foolbirdflyfirst 的回复:]

引用 10 楼 yangball 的回复:

但很明显 (a=) 这个有很多层,我都 + 来表示其有重复的情况了

按我的想法,匹配到一个然后入栈,依次循环才对的。

因为括号里的才推如捕获组。
比如类似串如:abcd
那我们知道/(a)(b)(c)(d)/的捕获组是0=>abcd,1=>a,2=>b,3=>c,4=>d,因为有4个()
那么如果是/(\w)*/,捕获组很容易知……
[/Quote]

恩,嘿嘿,只知道是被覆盖,原来是这样。thanks。
另外jordan的写法也不完善,如果<a=\d>的数量多一个,那么可能就匹配不到了。
foolbirdflyfirst 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yangball 的回复:]

但很明显 (a=) 这个有很多层,我都 + 来表示其有重复的情况了

按我的想法,匹配到一个然后入栈,依次循环才对的。
[/Quote]
因为括号里的才推如捕获组。
比如类似串如:abcd
那我们知道/(a)(b)(c)(d)/的捕获组是0=>abcd,1=>a,2=>b,3=>c,4=>d,因为有4个()
那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>a,这个*具体match的东西是不推入捕获组的,否则肯定很影响效率啊,这里只有4个字符,如果你捕获到成千上万个字符,难道一个个都推入捕获组么?

/<b=1>(?:\w*<a=(\d)>\w*)*<\/b>/
第一次match到1,推入$1
第二次match到2,还是推入$1
第三次match到3,依然推入$1
因为你整个正则式只有一对捕获的()啊,(?:..)是非捕获
床上等您 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ci1699 的回复:]

有正则的地方就有你们几个。
[/Quote]
进来学习学习。。。
等明天笨鸟哥来解答吧
ci1699 2011-11-23
  • 打赏
  • 举报
回复
有正则的地方就有你们几个。
床上等您 2011-11-23
  • 打赏
  • 举报
回复
但很明显 (a=) 这个有很多层,我都 + 来表示其有重复的情况了

按我的想法,匹配到一个然后入栈,依次循环才对的。
ohmygirl 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 foolbirdflyfirst 的回复:]

引用 4 楼 ohmygirl 的回复:

引用 3 楼 foolbirdflyfirst 的回复:

试试
PHP code
$str = 'asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=4>asdasd<a=5>dsa<a=6>ddd</b>czxxc';
$pat……


你好,foolbirdflyfir……
[/Quote]

哈,谢谢,柳暗花明又一村,了解点了。
ohmygirl 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yangball 的回复:]

对于 K,G这两个好像没什么资料谈及过

我觉得这里的正则,要实现在 X和Y之间去寻到具有循环的匹配。
我尝试用另一种方法去:

PHP code

//正则:
/<b=1>(?:\w*<a=(\d)>\w*)*<\/b>/
//但不成功,只能获取最后一个 3.
为什么呢?想不明白。。
[/Quote]

我刚开始的尝试跟你一样。但是这样会被覆盖的,也就是说,取到的是最后的一个值。
加载更多回复(6)

21,887

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧