找回密码
 加入
搜索
查看: 9082|回复: 15

[效率算法] 还是正则表达式的问题,正则能分 2段取值么(完了,结吧)

  [复制链接]
发表于 2011-5-13 20:12:02 | 显示全部楼层 |阅读模式
本帖最后由 lluxury 于 2011-5-15 23:30 编辑

数据有2种,要取的块我已标粗,现在有一个问题,就是取的这2个值有对应关系,正则能一次取2个值不,生成的是2维数组么?

第一种
8:43:27 对决:铁棒喇嘛 被:1 <普门杖法>
9:16:21 对决:麦兜 攻:1 被:1 <血刀刀法>
10:41:18 对决:蜡笔 被:1 <太极剑法>
11:2:27 对决:虫虫 攻:1 被:1
11:41:9 对决:我是非洲 被:1 <冲灵剑法>
23:45:23 对决:徐绩 攻:1 被:0 <飞星术>
8:6:6 对决:周青 攻:0 被:1 <驱蛇棍法 >
18:2:47 对决:橘子弟的pp 被:1 <蛇杖杖法>

取完第一种数据以后,再取第二种,生成的2个表我会合并一下
第二种
0228玄冥二老
与 玄冥二老 的对决开始!
小雏 率先发难!使出了入门武功[兰花拂穴手]!
玄冥二老 损失了 191 点体力~
玄冥二老 毫不手软!使出必杀[玄冥神掌]!
小雏 损失了 16 点体力~
玄冥二老 瞬间消失了。。。
  

0228赵志敬
与 赵志敬 的对决开始!
小雏 率先发难!使出了入门武功[兰花拂穴手]!
赵志敬 损失了 197 点体力~
赵志敬 毫不手软!使出必杀[七星剑法]!
小雏 损失了 0 点体力~
赵志敬 瞬间消失了。。。
发表于 2011-5-13 20:53:15 | 显示全部楼层
不用au3的正则,而用vbs正则,可以利用submatches来取得分组的内容,是可以得到这样的内容的。
 楼主| 发表于 2011-5-13 20:57:00 | 显示全部楼层
本帖最后由 lluxury 于 2011-5-13 20:58 编辑

回复 2# kevinch

这样啊,我查一下,另请问,au3的正则和vbs正则的什么区别呢?
分组的话,我在au3里用的是StringSplit,不过好像对汉字的适应性不好
发表于 2011-5-13 21:22:02 | 显示全部楼层
语法有点区别,用法也不同,但基本原理是一致的。
vbs正则在au3中使用要先创建项目objcreate("vbscript.regexp"),然后设置各个属性,再使用。
 楼主| 发表于 2011-5-13 21:22:06 | 显示全部楼层
本帖最后由 lluxury 于 2011-5-13 21:27 编辑

$a='8:43:27 对决:铁棒喇嘛 被:1 <普门杖法>'
$b=StringRegExp($a,'对决:([^ ]+)',3)
MsgBox(0,"",$b[0])    这是取人名的

$a='玄冥二老 毫不手软!使出必杀[玄冥神掌]!>'
$b=StringRegExp($a,'使出必杀\[([^]]+)',3)
MsgBox(0,"",$b[0])

单取是不难,关键是和人名字对应起来
要取到  铁棒喇嘛 普门杖法  这样的,
或着是取到2个数组里,下标相同的,彼此对应
发表于 2011-5-13 21:33:44 | 显示全部楼层
我试试AU3的正则能全提取出来吗?

#include <Array.au3>
Local $Str = _
                '第一种' & @CRLF & _
                '8:43:27 对决:铁棒喇嘛 被:1 <普门杖法>' & @CRLF & _
                '9:16:21 对决:麦兜 攻:1 被:1 <血刀刀法>' & @CRLF & _
                '10:41:18 对决:蜡笔 被:1 <太极剑法>' & @CRLF & _
                '11:2:27 对决:虫虫 攻:1 被:1' & @CRLF & _
                '11:41:9 对决:我是非洲 被:1 <冲灵剑法>' & @CRLF & _
                '23:45:23 对决:徐绩 攻:1 被:0 <飞星术>' & @CRLF & _
                '8:6:6 对决:周青 攻:0 被:1 <驱蛇棍法 >' & @CRLF & _
                '18:2:47 对决:橘子弟的pp 被:1 <蛇杖杖法>' & @CRLF & @CRLF & _
                '取完第一种数据以后,再取第二种,生成的2个表我会合并一下' & @CRLF & _
                '第二种' & @CRLF & _
                '0228玄冥二老' & @CRLF & _
                '与 玄冥二老 的对决开始!' & @CRLF & _
                '小雏 率先发难!使出了入门武功[兰花拂穴手]!' & @CRLF & _
                '玄冥二老 损失了 191 点体力~' & @CRLF & _
                '玄冥二老 毫不手软!使出必杀[玄冥神掌]!' & @CRLF & _
                '小雏 损失了 16 点体力~' & @CRLF & _
                '玄冥二老 瞬间消失了。。。' & @CRLF & _
                '  ' & @CRLF & @CRLF & _
                '0228赵志敬' & @CRLF & _
                '与 赵志敬 的对决开始!' & @CRLF & _
                '小雏 率先发难!使出了入门武功[兰花拂穴手]!' & @CRLF & _
                '赵志敬 损失了 197 点体力~' & @CRLF & _
                '赵志敬 毫不手软!使出必杀[七星剑法]!' & @CRLF & _
                '小雏 损失了 0 点体力~' & @CRLF & _
                '赵志敬 瞬间消失了。。。'
MsgBox(0, '原字符串', $Str)
Local $Test = StringRegExp($str, '(?<=对决:)(.*?)\h+.*?\<(.*?)\>|(.*?)\h+.*?(?<=\[)(.*?)(?=\]\!)', 3)
;~ If Not @Error Then MsgBox(0, '匹配数量: ' & UBound($Test), '其中[0]元素为: ' & $Test[0])
;~ _ArrayDisplay($Test, UBound($Test))
local $Fin[1][2],$k=1
for $i=0 to UBound($Test)-1 Step 2
        if Not $Test[$i]='' then 
                ReDim $Fin[$k][2]
                $Fin[$k-1][0]=$Test[$i]
                $Fin[$k-1][1]=$Test[$i+1]
                $k+=1
        EndIf
Next
_ArrayDisplay($Fin)
 楼主| 发表于 2011-5-13 22:08:01 | 显示全部楼层
本帖最后由 lluxury 于 2011-5-13 22:17 编辑

谢谢3m,我试试,

两段之间是用   | 连接的,  同段之间是怎么连接的呢
 楼主| 发表于 2011-5-13 22:11:13 | 显示全部楼层
本帖最后由 lluxury 于 2011-5-13 23:04 编辑

回复 6# 3mile

很强大,3m的品质果然有保证,^^

另外请问一下,如何把4种特征综合到一个正则里的呢

(?<=对决:)(.*?)\h+.*?\<(.*?)\>

我知道红字部分取的是名字,但后面部分的作用是什么呢   \h  这个始终没有明白
发表于 2011-5-14 00:25:22 | 显示全部楼层
回复 8# lluxury
其实3M写的虽然严谨,但是对于这种简单的例子用
对决:(\H+).*<([^>]+)|(\S+).+\[([^\]]+)
就足够了,这个应该比较容易懂,我没有挑刺的意思,只是为了让你看懂而已
 楼主| 发表于 2011-5-15 11:10:06 | 显示全部楼层
回复 9# love5173

还待改进,能稍微讲一下你的思路么

    [0]|第一种
8:43:27|普门杖法
[1]|>
9:16:21|血刀刀法
[2]|>
10:41:18|太极剑法
[3]|被:1
11:41:9|冲灵剑法
[4]|>
23:45:23|飞星术
[5]|>
8:6:6|驱蛇棍法
[6]|>
18:2:47|蛇杖杖法
[7]|小雏|兰花拂穴手
[8]|玄冥二老|玄冥神掌
[9]|小雏|兰花拂穴手
[10]|赵志敬|七星剑法
发表于 2011-5-15 20:45:00 | 显示全部楼层
本帖最后由 love5173 于 2011-5-15 20:58 编辑

回复 10# lluxury
不知道你是怎么测试的,如果我是没测试就发的那种我会说明的
#include <Array.au3>
Local $Str = _
                '第一种' & @CRLF & _
                '8:43:27 对决:铁棒喇嘛 被:1 <普门杖法>' & @CRLF & _
                '9:16:21 对决:麦兜 攻:1 被:1 <血刀刀法>' & @CRLF & _
                '10:41:18 对决:蜡笔 被:1 <太极剑法>' & @CRLF & _
                '11:2:27 对决:虫虫 攻:1 被:1' & @CRLF & _
                '11:41:9 对决:我是非洲 被:1 <冲灵剑法>' & @CRLF & _
                '23:45:23 对决:徐绩 攻:1 被:0 <飞星术>' & @CRLF & _
                '8:6:6 对决:周青 攻:0 被:1 <驱蛇棍法 >' & @CRLF & _
                '18:2:47 对决:橘子弟的pp 被:1 <蛇杖杖法>' & @CRLF & @CRLF & _
                '取完第一种数据以后,再取第二种,生成的2个表我会合并一下' & @CRLF & _
                '第二种' & @CRLF & _
                '0228玄冥二老' & @CRLF & _
                '与 玄冥二老 的对决开始!' & @CRLF & _
                '小雏 率先发难!使出了入门武功[兰花拂穴手]!' & @CRLF & _
                '玄冥二老 损失了 191 点体力~' & @CRLF & _
                '玄冥二老 毫不手软!使出必杀[玄冥神掌]!' & @CRLF & _
                '小雏 损失了 16 点体力~' & @CRLF & _
                '玄冥二老 瞬间消失了。。。' & @CRLF & _
                '  ' & @CRLF & @CRLF & _
                '0228赵志敬' & @CRLF & _
                '与 赵志敬 的对决开始!' & @CRLF & _
                '小雏 率先发难!使出了入门武功[兰花拂穴手]!' & @CRLF & _
                '赵志敬 损失了 197 点体力~' & @CRLF & _
                '赵志敬 毫不手软!使出必杀[七星剑法]!' & @CRLF & _
                '小雏 损失了 0 点体力~' & @CRLF & _
                '赵志敬 瞬间消失了。。。'
MsgBox(0, '原字符串', $Str)
Local $Test = StringRegExp($str, '对决:(\H+).*<([^>]+)|(\S+).+\[([^\]]+)', 3)
;~ If Not @Error Then MsgBox(0, '匹配数量: ' & UBound($Test), '其中[0]元素为: ' & $Test[0])
;~ _ArrayDisplay($Test, UBound($Test))
local $Fin[1][2],$k=1
for $i=0 to UBound($Test)-1 Step 2
        if Not $Test[$i]='' then 
                ReDim $Fin[$k][2]
                $Fin[$k-1][0]=$Test[$i]
                $Fin[$k-1][1]=$Test[$i+1]
                $k+=1
        EndIf
Next
_ArrayDisplay($Fin)

       至于思路其实跟3M差不多,只是没那么严谨
     楼主要的第一种是“对决:”后面的非空字符也就是\H+然后是任意字符一直到“<”出现,再取“>”前面的部分,这个结束
     第二种就简单了就是换行后面的非空白字符,因为牵扯到换行也是空白,所以用了\S+,后面的正则就跟第一种大同小异了
     因为第一种里面有<>第二种里面有[],所以,不用担心第一种第二种取到相同的字符串。
另外一点就是
    “'”这个符号在文本内时,可以不予以匹配,AU3正则会自动无视掉,而恰恰大部分的正则测试工具中需要匹配这个字符,所以当你发现别人给你的正则在测试工具中不好用时,要直接带到程序里测试,这样更保险,特别针对网页提取信息的人说的!
     还有就是因为AU3的正则在匹配的时候如果含有捕获组会造成,如果含有选择结构就会第一个捕获组捕捉不到内容就会取空值,而第二个表达式取不到值也没什么影响,造成了有些正则实际无法发挥他正常的作用,比如
(?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no 
这个正则在AU3中如果含有捕获组的表达式中是无法正常起到你要的作用的
     测试之前我先告诉你这个正则是跟(?(?=expression)yes | no) 功能一样的,但是AU3是不能识别上面的那个表达式的,下面的就可以。
     如果(?(?=expression)yes | no) 可以正常使用的话,3M下面那一段处理空值的循环就可以去掉了!
     最后,<>这两个符号,并不需要转意,可以直接在正则中使用,也就是\<是可以直接写<的。
     呵呵!

评分

参与人数 1金钱 +30 收起 理由
3mile + 30 解释的很清楚

查看全部评分

 楼主| 发表于 2011-5-15 21:59:55 | 显示全部楼层
本帖最后由 lluxury 于 2011-5-15 22:05 编辑
回复  lluxury
不知道你是怎么测试的,如果我是没测试就发的那种我会说明的

       至于思路其实跟3M差 ...
love5173 发表于 2011-5-15 20:45



    就是用你的正则表达式,替换3m的啊
发现了原因,我用的不是ie浏览器,对复制源码支持不好..给5173道歉





我自己也模仿写了一个,不过不对...

源码
<tr>
                <td width="100%">·15时56分、<font color=#6495ED><b>炸弹</b></font> 练成了 <font color=#CA9DE1><b>霹雳刀法</b></font>,似乎又要大干一番事业了</td>
        </tr>

代码
#6495ED><b>([^<]+)(.*?)\h+.*?#CA9DE1><b>([^<]+)

结果
[3]|炸弹
[4]|</b></font>
[5]|霹雳刀法


[4]是多余的,删不掉
发表于 2011-5-15 22:13:34 | 显示全部楼层
回复 12# lluxury

你里面的第二个括弧好像就是提取的[4]
 楼主| 发表于 2011-5-15 22:41:27 | 显示全部楼层
本帖最后由 lluxury 于 2011-5-15 22:42 编辑
回复  lluxury

你里面的第二个括弧好像就是提取的[4]
love5173 发表于 2011-5-15 22:13



恩,确实,解决
另之前说"3M下面那一段处理空值的循环"是哪一段呢?
发表于 2011-5-15 23:37:52 | 显示全部楼层
回复 14# lluxury
你不要问这么幼稚的问题,他代码里面只有一个循环结构!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-2 01:08 , Processed in 0.081185 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表