Board logo

标题: [文本处理] [已解决]如何用批处理提取字串中数字并用它生成新列? [打印本页]

作者: inittab    时间: 2009-6-14 10:53     标题: [已解决]如何用批处理提取字串中数字并用它生成新列?

有一节目表文件a.txt内容如下(问题更新):
  1. 09/06/14
  2. 01:40 电视剧:承诺(3)12
  3. 13:45 电视剧:康熙微服私访记222/30
  4. 03:14 电视剧:大明奇才 (第5集)
  5. 07:25 周末剧场 连续剧 开心老爸(16)
  6. 19:35 电视剧:我的丑娘26
  7. 19:11 电视剧:清凌凌的水蓝莹莹的天Ⅱ12/36
  8. 06:18 艺术人生:展现艺术家的人生
  9. 13:03 午间剧场:我叫金三顺(19—20)
  10. 08:12 剧场:宰相刘罗锅29
  11. 20:00 剧场:金婚(25——26)
  12. 13:44 剧场:情之缘21、22、23
  13. 17:45 天下故事
复制代码
请求写一批处理:有集数行后边加上(第X集)X的值从行中取得。表示日期的行,已带有第X集行,没数字的行均不处理),想了很久没搞定,请高手帮忙.

处理后如下效果:
09/06/14
01:40 电视剧:承诺(3)12 (第12集)
13:45 电视剧:康熙微服私访记222/30 (第22集)
03:14 电视剧:大明奇才 (第5集)
07:25 周末剧场 连续剧 开心老爸(16)(第16集)
19:35 电视剧:我的丑娘26  (第26集)
19:11 电视剧:清凌凌的水蓝莹莹的天Ⅱ12/36 (第12集)
06:18 艺术人生:展现艺术家的人生
13:03 午间剧场:我叫金三顺(19—20)(第19集)
08:12 剧场:宰相刘罗锅29 (第29集)
20:00 剧场:金婚(25——26) (第25集)
13:44 剧场:情之缘21、22、23 (第21集)
17:45 天下故事

[ 本帖最后由 inittab 于 2009-6-16 10:40 编辑 ]
作者: keen    时间: 2009-6-14 14:55

这个是笔误,还是别的:
03:14 电视剧:大明奇才 (第5集)

03:14 电视剧:大明奇才5/30 (第5集)

作者: 随风    时间: 2009-6-14 15:02

12:47 电视剧:康熙微服私访记221/30 (第21集)
13:45 电视剧:康熙微服私访记222/30 (第22集)
这才是讨厌的地方,电视名和集数之间居然没有任何分隔符?
还有这一句,无法找到整个的规律 01:40 电视剧:承诺(3)12

[ 本帖最后由 随风 于 2009-6-14 15:04 编辑 ]
作者: namejm    时间: 2009-6-14 15:02

  最重要的一点:在众多的数字中,哪些数字代表集数?像“康熙微服私访记221/30 ”这样的字符串中,集数为什么是21而不是221——虽然我知道总集不能超过30,所以它只能是21而不能是221,但老兄你总得告诉我怎么区分哪些是集数吧?
作者: tab    时间: 2009-6-14 15:22

康熙微服私访记221/30 是康熙微服私访记2共30集,这是第21集。我是这样看的。
  1. s/[ \t]*$//
  2. s/)[0-9][0-9]/& (第&集)/;s/第)/第/
  3. s#[0-9][0-9]/.*#& (第&集)#
  4. s#[0-9]/.*#& (第&集)#
  5. s/集).*/集)/1
  6. s#(第.*/.*/.*##
  7. /:/s#/[0-9][0-9]##2;/:/s#/[0-9]##2
复制代码

以上代码复制到1.txt中
在命令行输入
  1. sed -f 1.txt a.txt
复制代码

作者: tab    时间: 2009-6-14 15:25

有些时候电视剧不同的集数不是从同一服务器下载的,名称可能会不同。
作者: zljzsmzzx    时间: 2009-6-14 19:48

你帖的这个列表也太乱了吧。像“康熙微服私访记221/30”“康熙微服私访记222/30”这样没有偏离其它太多的倒是可以根据后面的总集数来判断。但像“承诺(3)12”这样的根本没法判断了。而这只是你例举出来的一部分吧,保不准还有其它更“离谱”的呢。如果可能的话,楼主自己应该先总结出一个规律出来,这样我们才好帮你。因为我们看不到你的全部“列表”。根本不可能未卜先知的给你定一个完美的规律。所以最好能帖上列表中能代表全部列表的例子
作者: inittab    时间: 2009-6-14 21:13

谢谢大家回复!

是这样的,难点就是这里。节目表是网站采集下来的。很多的不严谨

如果手工处理。基本上不太可能。重要的是要把集数取出来。以便后续程序处理有规律化处理(根据集数再进一步采集剧情等),美观与否倒是次要。(^_#).
象 "康熙微服私访记221/30 实际节目名是"康熙微服私访记2" 连在一起了。另外
"承诺(3)12 " 也是类似,12是集数。"03:14 电视剧:大明奇才 (第5集) " 本身带就有的,不需要处理。
还有些是(21-22) 和21、22、23 这样的。

如果有多集情况取第一集就可以了。

典型几种情况已更新在顶楼

别外,感谢5楼 tab 热心帮忙,也期待论坛高手精彩的代码,学习ing ~

[ 本帖最后由 inittab 于 2009-6-14 22:01 编辑 ]
作者: namejm    时间: 2009-6-14 21:49

  建议把更新后的内容发到顶楼,别人在一楼看到的永远是最新的要求,这样才方便新来的人了解你的最新要求——假如回复帖有5页10页,而你的要求散落在各个楼层,写个代码还得从头到尾把所有帖子都看一遍,并且还得在你的最新要求那个帖子上做个标记,你就知道想帮你的人是何等痛苦了。
作者: inittab    时间: 2009-6-14 22:03     标题: 回复 9楼 的帖子

谢谢提醒,已更新到顶楼。不再改了。
作者: jackerloo2009    时间: 2009-6-14 22:09     标题: 回复 1楼 的帖子

07:25 周末剧场 连续剧 开心老爸(16)
07:25 周末剧场 连续剧 开心老爸(16)(第6集)
这个也是笔误吧?
作者: inittab    时间: 2009-6-14 22:11     标题: 回复 11楼 的帖子

是的,呵呵,手动填的。已改正
作者: inittab    时间: 2009-6-14 22:32

我先给个自己写的临时在用有些缺陷的代码(某些行不能处理或有错)
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3. set tt0=%%i&set "v0="
  4. if not "!tt0:~2,1!"=="/" (
  5. for /f "tokens=1,2 delims=/-" %%m in ('echo %%i ^| sed -e "s/—/-/" -e "s/、/-/" -e "s/[^0-9/-]//g"') do (
  6. set v0=%%m&set v0=!v0:~4!&if not "%%n"=="" if !v0! gtr %%n (set v0=!v0:~1!)))
  7. if not "!v0!"=="" (echo\%%i ^(第!v0!集^)) else echo\%%i
  8. )
  9. pause
复制代码
sed 下载:http://www.vkill.net/tools.html

发现一个比较怪的问题,for () 里的echo %%i  不能用echo !tt0! 代替。本来想用echo !tt0:~-10!的倒取10个字符的可是发现不行。

[ 本帖最后由 inittab 于 2009-6-14 22:43 编辑 ]
作者: tab    时间: 2009-6-15 08:04

给你改动一下。
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3. set tt0=%%i&set "v0="
  4. if not "!tt0:~2,1!"=="/" (
  5. for /f "tokens=1,2 delims=/-" %%m in ('echo %%i ^| sed "/.第.*/d;s/)../&-100/;s/—/-/;s/、/-/;s/[^0-9/-]//g"') do (
  6. set v0=%%m&set v0=!v0:~4!&if not "%%n"=="" if !v0! gtr %%n (set v0=!v0:~1!)))
  7. if not "!v0!"=="" (echo\%%i ^(第!v0!集^)) else echo\%%i
  8. )
  9. pause
复制代码


不过说实话,代码效率不高

[ 本帖最后由 tab 于 2009-6-15 08:13 编辑 ]
作者: inittab    时间: 2009-6-15 08:31

不是不高,是很低效的,超级慢。就像把把水抽干了捕鱼。呵呵
作者: terse    时间: 2009-6-15 23:21

这样用 SED 还不如用批处理 同样的不通用
修正最后字符为“)”的话不能取到集数问题
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%i in (0 1 9) do set "_%%i=%%i"
  3. for /f "usebackq delims=" %%i in ("a.txt") do (
  4.   set var=%%i
  5.   for /f "tokens=1*" %%a in ("%%i") do (
  6.      if "%%b" neq "" (
  7.      set str=%%b&call:lp
  8.      if not "!e!"=="" for %%e in (!e!) do set var=!var:*%%e=!
  9.    )
  10.   if "!var!"=="%%i" (echo !var! !e!)else echo %%i
  11. set e=
  12. ))
  13. pause&exit
  14. :lp
  15. if defined str (
  16.    set v=!str:~,1!
  17.        if defined e (
  18.        set e1=!str:~1!
  19.        if defined _!v! (set e=!e!!v!) else (
  20.        if "!v!"==")" if defined e1 set "e="&goto lp
  21.        if "!v!"=="/" (
  22.        if !e! gtr !e1! set e=!e:~1!
  23.      )
  24.        set e=第!e!集&exit/b)
  25.      ) else if defined _!v! set e=!v!
  26.        set str=!str:~1!
  27.       goto lp
  28.   )
  29. if not "!e!"=="" set e=第!e!集
复制代码

[ 本帖最后由 terse 于 2009-6-16 09:03 编辑 ]
作者: inittab    时间: 2009-6-15 23:52

terse 兄有好的思路么?

13:45 电视剧:康熙微服私访记222/30
这条可以不考虑。
作者: tab    时间: 2009-6-16 08:42

terse兄的代码很好。
在处理文本方面,本就没有通用的代码,都是有针对性的,或说是局限性。
下面是1.txt内容,很懒,就不再简化了,不过效率还是不错的。
  1. s/[ \t]*$/%/
  2. s/)[0-9][0-9]/& (第&集)/;s/第)/第/
  3. s#[0-9][0-9]/.*#& (第&集)#
  4. s#[0-9]/.*#& (第&集)#
  5. s/集).*/集)/1
  6. s#(第.*/.*/.*##
  7. /:/s#/[0-9][0-9]##2;/:/s#/[0-9]##2
  8. /、/s/..、..、../& (第&/;s/、..、..%$/集)/
  9. s/(.*)/& (第&集)/;s/第(/第/;s/)集/集/;s/—..集/集/
  10. /——/s/(.*/& (第&集/;s/——..)%集/集)/;s/第(/第/
  11. s/%//
  12. /:/s/[0-9][0-9]$/& (第&集)/
  13. s/%//
复制代码

作者: inittab    时间: 2009-6-16 10:28

谢谢各位了。先把它结掉,
有更好的代码请继续。




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2