免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7485 | 回复: 16
打印 上一主题 下一主题

正则表达式解析xml时遇到的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-08 14:14 |只看该作者 |倒序浏览
比如这样一个字符串:
<AAA>TEST</AAA><BBB>Test</BBB><AAA>test</AAA><BBB>TesT</BBB>

正则表达式应该怎么写才能提取出“TEST”?

用sed 's/<AAA>\(.*\)<\/AAA>.*/\1/'只能得到:TEST</AAA><BBB>Test</BBB><AAA>test

另外,为什么sed 's/<AAA>\(.*\)<\/AAA>/\1/'得到的结果是TEST</AAA><BBB>Test</BBB><AAA>test<BBB>TesT</BBB>
<BBB>TesT</BBB>是怎么来的?

论坛徽章:
0
2 [报告]
发表于 2008-01-08 14:27 |只看该作者
  1. sed -r 's:<AAA>([^<>]*)</AAA>.*:\1:'
复制代码
  1. echo '<AAA>TEST</AAA><BBB>Test</BBB><AAA>test</AAA><BBB>TesT</BBB>'|perl -ne 'print $1 if m:<AAA>(.*?)</AAA>:'
复制代码


不知道sed的?有没有用...

论坛徽章:
0
3 [报告]
发表于 2008-01-08 14:29 |只看该作者

  1. sed 's/<AAA>\([^<]*\)<\/AAA>.*/\1/'
复制代码

论坛徽章:
0
4 [报告]
发表于 2008-01-08 14:40 |只看该作者
原帖由 baicj 于 2008-1-8 14:14 发表
比如这样一个字符串:
TESTTesttestTesT

正则表达式应该怎么写才能提取出“TEST”?

用sed 's/\(.*\).*/\1/'只能得到:TESTTesttest

另外,为什么sed 's/\(.*\)/\1/'得到的结果是TESTTesttestTesT?
...


正则表达式匹配 按照最长匹配原则 ,也就是说 “/<aaa>.*<aaa>/匹配最长的 <aaa>囊括的字符串
对于你给的输入和正则表达式:

<AAA>TEST</AAA><BBB>Test</BBB><AAA>test</AAA><BBB>TesT</BBB>


用sed 's/<AAA>\(.*\)<\/AAA>.*/\1/'
\1代表最长的<AAA>之间的字符 : <AAA>TEST</AAA><BBB>Test</BBB><AAA>test</AAA>
所以只能得到:TEST</AAA><BBB>Test</BBB><AAA>test

另外,sed 's/<AAA>\(.*\)<\/AAA>/\1/'只替换了 <aaa>中间的部分,后面的 <bbb>部分没变化,自然
得到的结果是TEST</AAA><BBB>Test</BBB><AAA>test<BBB>TesT</BBB>?

[ 本帖最后由 jinl 于 2008-1-8 14:44 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-01-08 14:50 |只看该作者


  1. echo 'string' | gawk '{print gensub(/<AAA>([^<]*)<\/AAA>.*/,"\\1",1)}'
复制代码

论坛徽章:
0
6 [报告]
发表于 2008-01-08 14:53 |只看该作者
明白了,谢谢三位!
看来perl脚本可以解决这个问题。

另外,如果是<AAA><BBB>TEST</BBB></AAA><AAA></AAA>这种情况呢,sed有没有可能取出第一个AAA的内容?

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
7 [报告]
发表于 2008-01-08 14:57 |只看该作者
原帖由 baicj 于 2008-1-8 14:53 发表
明白了,谢谢三位!
看来perl脚本可以解决这个问题。

另外,如果是TEST这种情况呢,sed有没有可能取出第一个AAA的内容?


这不和你的第一个问题一样么?

论坛徽章:
0
8 [报告]
发表于 2008-01-08 14:59 |只看该作者
不好意思,理解错了…三位的表达式都没有问题,谢谢

论坛徽章:
0
9 [报告]
发表于 2008-01-08 15:11 |只看该作者
= =!
刚才测试了一下<AAA><BBB>TEST</BBB></AAA><AAA></AAA>,的确sed和awk的表达式不行,因为有[^<]*

是不是正则表达式的最大匹配原则让这种情况不能实现?除非用扩展的正则表达式,比如perl?

论坛徽章:
0
10 [报告]
发表于 2008-01-08 15:17 |只看该作者
原帖由 baicj 于 2008-1-8 15:11 发表
= =!
刚才测试了一下TEST,的确sed和awk的表达式不行,因为有[^
a
awk应该可以实现阿,
awk -F "<[\]?AAA>" '{ print $1}'

[ 本帖最后由 jinl 于 2008-1-8 15:22 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP