SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 1943|回复: 10
打印 上一主题 下一主题

请教正则表达式

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2009-12-20 14:57:32 | 只看该作者

请教正则表达式

data old;
   input name $60.;
   datalines;
Judith S Reaveley
Ralph F. Morgan
Jess Ennis
Carol Echols
Kelly Hansen Huff
Judith
Nick
Jones
;

data new;
   length first middle last $ 40;
   re1 = prxparse('/(\S+)\s+([^\s]+\s+)?(\S+)/o');
   re2 = prxparse('/(\S+)\(s+)([^\s]+\s+)(?)(\S+)/o');
   set old;
   id=prxmatch(re1, name);
   if id then
      do;
         first = prxposn(re1, 1, name);
         middle = prxposn(re1, 2, name);
         last = prxposn(re1, 3, name);
      end;
   test = prxposn(re2, 4, name);
run;

我有4个问题:
1.为什么re2定义是错误的?
2.在re1定义中,为什么有的加括号,如\S+,有的又不加,如\s+?加括号和不加括号有什么不一样呢?
3.斜杠最后的那个o是什么意思?查help没有查到。
4.prxposn函数第二个参数叫capture-buffer,翻译成中文是什么意思呢?

多谢大侠赐教!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2009-12-21 15:53:04 | 只看该作者

Re: 请教正则表达式

呵呵,我也是第一次看到有人用perl语句。因为你的问题我看了看SAS 9.1的help文档,你的问题在SAS 9.1.3的help文档里都有的,我在这先现学现卖一下,呵呵,等真正的专家来了请他们彻底解决你的问题吧。

问题1:/*1.为什么re2定义是错误的?*/
回答:注意看后面的解答2。re2 = prxparse('/(\S+)[color=#FF0000:3hncmk3j]\([/color:3hncmk3j]s+)([^\s]+\s+)(?)(\S+)/o');

问题2:/*2.在re1定义中,为什么有的加括号,如\S+,有的又不加,如\s+?加括号和不加括号有什么不一样呢?*/
(pattern)  matches a pattern and creates a capture buffer for the match. To retrieve the position and length of the match that is captured, use CALL PRXPOSN. To retrieve the value of the capture buffer, use the PRXPOSN function. To match parentheses characters,use [color=#FF0000:3hncmk3j] "\(" or "\)". [/color:3hncmk3j]

问题3:/*3.斜杠最后的那个o是什么意思?查help没有查到。*/
If perl-regular-expression is a constant or if it uses the /o option, then the Perl regular expression is compiled once and each use of PRXCHANGE reuses the compiled expression. If perl-regular-expression is not a constant and if it does not use the /o option, then the Perl regular expression is recompiled for each call to PRXCHANGE.

问题4:/*4.prxposn函数第二个参数叫capture-buffer,翻译成中文是什么意思呢?*/
我觉得可以翻译成:匹配器/俘获器?(胡乱译的,不要当真。)主要是它的原义,可见问题2的解答:“matches a pattern and creates a capture buffer for the match”。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2009-12-21 20:11:45 | 只看该作者

Re: 请教正则表达式

多谢大侠如此细致的回复。不过我对于第二个问题还是有点疑问,为什么原来的正则表达式中的1;3;5位置上使用了括号,而2;4位置上只是用\s+和?来表示?我说的意思不是你回答的只有左括号或右括号的问题。多谢了!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2009-12-22 09:02:52 | 只看该作者

Re: 请教正则表达式

我也不知道哦,其实我对Perl也不熟,因为你的问题才看了看SAS的help文档。
我把我自己的理解写在下面([color=#FF8000:39gp6z7m]非官方解释,不要当真[/color:39gp6z7m]。期待高手解答):
括号的作用就是为了matches a pattern and creates a capture buffer for the match.也就是说加在括号里的字符必须符合perl语句的要求,例如re1 = prxparse('/(\S+)\s+([^\s]+\s+)?(\S+)/o');
[color=#FF0000:39gp6z7m]第一部分[/color:39gp6z7m]:“(\S+)”:我们把“\S”和“+”独立出来看(在SAS Functions and CALL Routines 中的Pattern Matching Using SAS Regular Expressions (RX) and Perl Regular Expressions (PRX)页面下有关于这两个对应字符的解释,我也说不清楚,你自己找出来看看。),然后匹配你的示例数据“Judith S Reaveley”的第一个词“Judith”。
[color=#FF0000:39gp6z7m]第二部分[/color:39gp6z7m]“\s+”:和第一部分同理分解看SAS的help解说。然后匹配的示例数据“Judith S Reaveley”的第二部分字符“ ”。(什么都没有,对了,就是一个空格。)
[color=#FF0000:39gp6z7m]第三部分[/color:39gp6z7m]“([^\s]+\s+)”。。。
最后:
first = prxposn(re1, [color=#FF0000:39gp6z7m]1[/color:39gp6z7m], name);
middle = prxposn(re1, [color=#FF0000:39gp6z7m]2[/color:39gp6z7m], name);
last = prxposn(re1, [color=#FF0000:39gp6z7m]3[/color:39gp6z7m], name);

我刚才突然想到估计这些你自己都已经分析到了,呵呵。至于为什么re2和re1到底是什么区别,我自己还要琢磨琢磨。
re2中括号的作用还没有运行出结果,re2是你自己写的吗?你是想通过括号定位来将相应的数据提出来?如果是这样,我自己还要琢磨琢磨。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2009-12-22 10:52:34 | 只看该作者

Re: 请教正则表达式

刚才写的可能不太准确,现在发现最大的问题是寄存器的括号不匹配是主因。以下两种写法都是合法的。只是匹配目的是不一样的。

re2 = prxparse('/(\S+)(\s+)([^\s]+\s+)(?)(\S+)/o');
re2 = prxparse('/(\S+)(s+)([^\s]+\s+)(?)(\S+)/o');
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2009-12-22 12:43:10 | 只看该作者

Re: 请教正则表达式

多谢aHuige和tanzhen_mysas ,Ahuige用的寄存器真的很形象。\(s+不合法,合法的是:\(\s+,但是我还是对为什么在第二个位置上用s+而不能用(s+)呢?难道(s+)就不能寄存?或者说空格(因为s表示空格等含义)就不能寄存?同样的还有第五个位置?,为什么不能用(?),而对于第一个位置就可以用()?是不是SAS寄存器只能寄存数字和字符?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2009-12-22 13:23:36 | 只看该作者

Re: 请教正则表达式

一切都是括号没匹配造成的。你去一个个的标出来看看,哪些东西是寄存器的括号,哪些是括号字符就知道了。如果寄存器的括号不匹配,结果就非法了。你的其他问题也不用回答了,语法正确了就都不是问题了。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2009-12-22 16:46:47 | 只看该作者

Re: 请教正则表达式

多谢Ahuige!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2009-12-23 11:54:36 | 只看该作者

Re: 请教正则表达式

多谢各位大侠的指点,现在又遇到一个很有意思的问题,请看下面的测试代码:
data test;
input x$;
cards;
abc,def
man,feman
;
run;

data b;
set test;
if _n_=1 then re=PRXPARSE("/(\w+),(\w+)/");
retain re;
id=prxmatch(re,x);
if id then do;
r1=PRXPOSN(re,1,x);
r2=PRXPOSN(re,2,x);
end;
run;

注意我定义的正则表达式中间有一个逗号,这个逗号是正则表达式的元字符吗?我只发现HELP里面有*;+和?,但是怎么也找不到逗号作为元字符。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2009-12-23 14:40:13 | 只看该作者

Re: 请教正则表达式

观察一下数据吧,这只是一个普通逗号。数据里不是有括号嘛。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2026-2-6 11:24 , Processed in 0.115193 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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