lluxury 发表于 2011-5-13 20:12:02

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

本帖最后由 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 点体力~
赵志敬 瞬间消失了。。。

kevinch 发表于 2011-5-13 20:53:15

不用au3的正则,而用vbs正则,可以利用submatches来取得分组的内容,是可以得到这样的内容的。

lluxury 发表于 2011-5-13 20:57:00

本帖最后由 lluxury 于 2011-5-13 20:58 编辑

回复 2# kevinch

这样啊,我查一下,另请问,au3的正则和vbs正则的什么区别呢?
分组的话,我在au3里用的是StringSplit,不过好像对汉字的适应性不好

kevinch 发表于 2011-5-13 21:22:02

语法有点区别,用法也不同,但基本原理是一致的。
vbs正则在au3中使用要先创建项目objcreate("vbscript.regexp"),然后设置各个属性,再使用。

lluxury 发表于 2011-5-13 21:22:06

本帖最后由 lluxury 于 2011-5-13 21:27 编辑

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

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

单取是不难,关键是和人名字对应起来
要取到铁棒喇嘛 普门杖法这样的,
或着是取到2个数组里,下标相同的,彼此对应

3mile 发表于 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), '其中元素为: ' & $Test)
;~ _ArrayDisplay($Test, UBound($Test))
local $Fin,$k=1
for $i=0 to UBound($Test)-1 Step 2
        if Not $Test[$i]='' then
                ReDim $Fin[$k]
                $Fin[$k-1]=$Test[$i]
                $Fin[$k-1]=$Test[$i+1]
                $k+=1
        EndIf
Next
_ArrayDisplay($Fin)

lluxury 发表于 2011-5-13 22:08:01

本帖最后由 lluxury 于 2011-5-13 22:17 编辑

谢谢3m,我试试,

两段之间是用   | 连接的,同段之间是怎么连接的呢

lluxury 发表于 2011-5-13 22:11:13

本帖最后由 lluxury 于 2011-5-13 23:04 编辑

回复 6# 3mile

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

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

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

我知道红字部分取的是名字,但后面部分的作用是什么呢   \h这个始终没有明白

love5173 发表于 2011-5-14 00:25:22

回复 8# lluxury
其实3M写的虽然严谨,但是对于这种简单的例子用对决:(\H+).*<([^>]+)|(\S+).+\[([^\]]+)就足够了,这个应该比较容易懂,我没有挑刺的意思,只是为了让你看懂而已

lluxury 发表于 2011-5-15 11:10:06

回复 9# love5173

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

    |第一种
8:43:27|普门杖法
|>
9:16:21|血刀刀法
|>
10:41:18|太极剑法
|被:1
11:41:9|冲灵剑法
|>
23:45:23|飞星术
|>
8:6:6|驱蛇棍法
|>
18:2:47|蛇杖杖法
|小雏|兰花拂穴手
|玄冥二老|玄冥神掌
|小雏|兰花拂穴手
|赵志敬|七星剑法

love5173 发表于 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), '其中元素为: ' & $Test)
;~ _ArrayDisplay($Test, UBound($Test))
local $Fin,$k=1
for $i=0 to UBound($Test)-1 Step 2
      if Not $Test[$i]='' then
                ReDim $Fin[$k]
                $Fin[$k-1]=$Test[$i]
                $Fin[$k-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下面那一段处理空值的循环就可以去掉了!
   最后,<>这两个符号,并不需要转意,可以直接在正则中使用,也就是\<是可以直接写<的。
   呵呵!

lluxury 发表于 2011-5-15 21:59:55

本帖最后由 lluxury 于 2011-5-15 22:05 编辑

回复lluxury
不知道你是怎么测试的,如果我是没测试就发的那种我会说明的

       至于思路其实跟3M差 ...
love5173 发表于 2011-5-15 20:45 http://autoitx.com/images/common/back.gif


    就是用你的正则表达式,替换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>([^<]+)

结果
|炸弹
|</b></font>
|霹雳刀法


是多余的,删不掉

love5173 发表于 2011-5-15 22:13:34

回复 12# lluxury

你里面的第二个括弧好像就是提取的

lluxury 发表于 2011-5-15 22:41:27

本帖最后由 lluxury 于 2011-5-15 22:42 编辑

回复lluxury

你里面的第二个括弧好像就是提取的
love5173 发表于 2011-5-15 22:13 http://autoitx.com/images/common/back.gif


恩,确实,解决
另之前说"3M下面那一段处理空值的循环"是哪一段呢?

love5173 发表于 2011-5-15 23:37:52

回复 14# lluxury
你不要问这么幼稚的问题,他代码里面只有一个循环结构!
页: [1] 2
查看完整版本: 还是正则表达式的问题,正则能分 2段取值么(完了,结吧)