免费注册 查看新帖 |

Chinaunix

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

求高人指导 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-23 22:09 |只看该作者 |倒序浏览
有很多个文件,文件中的数据可能有重复的部分,现在需要把重复的加一个标记,求实现方式。
例如,数据可能如下:
<aa>****************<bbbb>****************<aa>***************<ccc>***********************
<dddddddddddddd>*******************<eeeeeeee>***************<bbbb>**********************************************
<ccc>*****************************************************************************<aa>

*代表其他不需要的数据,需要的数据在尖括号内

想要得到以下结果(第二次以及以后出现时,在前面加个标记,先后顺序并不重要):

<aa>****************<bbbb>****************repe<aa>***************<ccc>***********************
<dddddddddddddd>*******************<eeeeeeee>***************repe<bbbb>**********************************************
repe<ccc>*****************************************************************************repe<aa>

求高人指导实现方法,现在只能写到:

while(<>){
             
              if(@am=/\<.*?\>/g){
              foreach $b(@am){
              $tmp{$b}++;
              if($tmp{$b}>2){
                        *******;
              }
问题是,重复的是找到了,但没法对其操作啊,更没法在前面加东西,求高人指点迷津,多谢!

论坛徽章:
0
2 [报告]
发表于 2012-11-23 23:08 |只看该作者
本帖最后由 kk861123 于 2012-11-23 23:08 编辑

回复 1# pinkkyone
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %attr;
  5. while (<DATA>) {
  6.     s|(<[^>]+>)| $attr{$1}++ ? "repe$1" : $1|xeg;
  7.     print;
  8. }

  9. __DATA__
  10. <aa>****************<bbbb>****************<aa>***************<ccc>***********************
  11. <dddddddddddddd>*******************<eeeeeeee>***************<bbbb>**********************************************
  12. <ccc>*****************************************************************************<aa>
复制代码

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
3 [报告]
发表于 2012-11-23 23:51 |只看该作者
不知道楼主最终的目的是什么.

单就现在的说法来看, 这个程序写出来效率也不高, 因为有大量反复的递归正则.

建议楼主调整一下思路.

论坛徽章:
0
4 [报告]
发表于 2012-11-24 18:05 |只看该作者
回复 2# kk861123

多谢,所提供的代码运行后可得到正确的结果。
我把问题简化了,本来的数据是这样的:
<Tu MatchPercent="100"><Tuv Lang="EN-US">upgrading</Tuv><Tuv Lang="ZH-CN"><df Font="宋体">升级</df></Tuv></Tu>

upgrading即相当于上例中的aa或ccc部分等,它们都在<Tuv Lang="EN-US">和<Tuv Lang="ZH-CN">之内。

最终的目的是:如果发现重复的upgrading等,则判断前一个<>内有没有 origin="Repe" 属性,如果没有,则添加该属性,最终的结果为:

<Tu Origin="Repe" MatchPercent="100"><Tuv Lang="EN-US">upgrading</Tuv><Tuv Lang="ZH-CN"><df Font="宋体">升级</df></Tuv></Tu>


请问,根据您提供的思路,是否能实现?


   

论坛徽章:
0
5 [报告]
发表于 2012-11-24 18:12 |只看该作者
回复 3# q1208c

如楼上所述,这些文件都是XML文件,最终目的就是为重复部分添加一个属性,以便该部分不被专门处理此文件的程序处理,待文件处理完成后,用仅留的一个处理好的数据结果,去替换其它重复的部分。

本人是程序新人,perl也才学没几天,都是工作所逼才硬着头皮去查书,目前小骆驼还没读完,所以上述思路肯定不完善,或者说压根就想错了也说不定,希望各路好人不吝赐教,感激不尽。
   

论坛徽章:
0
6 [报告]
发表于 2012-11-24 20:25 |只看该作者
本帖最后由 pinkkyone 于 2012-11-24 20:27 编辑

其实这是一个XML文件的翻译问题,锁定重复的部分,可以避免重复劳动。重新思考了一遍,我现在的需求如下:

文件前处理:

1. 在所有文件中搜索类似如下的数据块。其中Origin="Repe"不一定有的,"<df Font="宋体">和</df>这对标签也不一定有的。"upgrading"部分是英文,“升级”是译文,它们是可变的:

<Tu Origin="Repe" MatchPercent="100"><Tuv Lang="EN-US">upgrading</Tuv><Tuv Lang="ZH-CN"><df Font="宋体">升级</df></Tuv></Tu>

2.如果第一个标签内已含有Origin="Repe",则把作为Target的“升级”变为“升级lalala”(加一个标记lalala,或其他标记,目的是为以后处理方便)。

3.如果第一个标签内不含Origin="Repe",则判断英文upgrading部分是第几次出现,如果是第一次出现,不做操作;如果是第二次或更多次出现,在第一个标签内加上Origin="Repe"标记。

文件后处理:

1.第一遍,搜索所有第一个标签内不带Origin="Repe"的数据块,建一个哈希表,将例如"upgrading"和“升级”的数据分别作为键和值放入其中,即有了全部英文译文对照表。

2.第二遍,搜索第一个标签内带Origin="Repe"的数据块,如果其译文部分带lalala,则不如本次处理范围,不做操作;如果其译文部分不带lalala,则其必为前处理时锁定的部分,在第一遍建立的哈希表中搜索其对应的译文,替换到Target部分。

3.删掉所有lalala(添加的标记字符)。



本人虽然愚钝,但写这么多不是为求一个写好的答案,只是求一个处理方法,例如:

1.如何在用正则扎到一个大块匹配的时候,再根据某些条件(例如前处理中的 2. 3)分别对找到的该大块中的某些小块进行所需的操作?

2.如何将操作后的结果直接写到文件?例如,我通过数组保存第一步拆分的小块结果时,如何将对数组元素的操作结果写回到拆分前的大块中?


感觉有话无法告诉perl怎么处理(程序语言也是语言啊...,心里明白,无法告诉perl去这样做),或者说,根本没法做这样的处理?
其实有现有方法可以进行这个处理,可是要借助第三方工具,速度比较慢,处理1M数据差不多要1分钟,从这个速度上说,我对perl的要求并不高,50M数据别超过几分钟就行...
上传了一个文件,如感兴趣,可以参考,此文件中即有重复部分。

1.xml.zip

4.13 KB, 下载次数: 2

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
7 [报告]
发表于 2012-11-25 01:52 |只看该作者
回复 5# pinkkyone

perl 应该有专门处理 xml的mod. 我没用过. 你可以试着找找.

如果只是把这个 xml 文件做为文本来处理, 你那个要求如果实现的话, 还有点复杂.

因为要记数, 所以, 要对所有的标签都要计数, 可能需要一个 tagHash, 又因为你的标签不一定是在同一行中, 而同一行中也可能有两个以上的标签, 所以, 对行的处理也很麻烦. 要考虑这两种情况.


   

论坛徽章:
0
8 [报告]
发表于 2012-11-25 09:15 |只看该作者
回复 4# pinkkyone
  1. <Tu Origin="Repe" MatchPercent="100"><Tuv Lang="EN-US">upgrading</Tuv><Tuv Lang="ZH-CN"><df Font="宋体">升级</df></Tuv></Tu>
复制代码
你的意思是,"upgrading"和“升级”是属于重复的内容,就给Tu添加一个Origin="Repe"的属性对吗?
另外,我建议你使用专门解析XML的模块来处理,XML::Simple

论坛徽章:
0
9 [报告]
发表于 2012-11-25 11:56 |只看该作者
回复 7# q1208c

说的非常对,要先找到这些标签,再对其计数。
标签不一定在一行中,一行也可能有多个标签,这确实可能有点麻烦,呵呵。

也许按照文本的处理方式没法实现...?总觉得是可以的,我对效率要求不高...


   

论坛徽章:
0
10 [报告]
发表于 2012-11-25 12:00 |只看该作者
回复 8# kk861123

是的,,"upgrading"和“升级”一个是source一个是target,只要判断source是重复的就可以了。

我是windows环境,对模块安装不太熟悉,先安装下试试吧,不过还是对不使用模块实现有点兴趣,呵呵...

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP