Board logo

标题: [文本处理] 【已解决】批处理如何识别并提取文本中存在的11位手机号? [打印本页]

作者: taofan712    时间: 2017-2-9 10:53     标题: 【已解决】批处理如何识别并提取文本中存在的11位手机号?

本帖最后由 taofan712 于 2017-2-10 20:59 编辑
  1. 寒蝉凄13切,对长亭晚,13311111111骤雨初歇。
  2. 都门帐饮无绪,留恋处舟催发。执手相看[color=Red]1355555
  3. 7777[/color]泪眼,竟无语凝噎。念15去135去千里烟波,
  4. 暮霭沉1314沉楚天阔。  多情自古12580伤离别,
  5. 更那堪冷落清秋节。今宵酒醒何处?136杨柳岸晓风10010残月。
  6. 1372222此444去经年,应是良辰好景虚设。
  7. 便纵10086有千种风情,更与何人说? 13788889999
复制代码
——————————————————
假设有类似文本,请问如何批处理自动识别其中的手机号码,并提取出来?
作者: B魔方大人    时间: 2017-2-9 11:54

首先手机号是一串数字,至于多长,是不一定的.如果单纯以移动联通为标准.那么哥已经帮你提取出来了.就这两条.不客气.
13311111111
13788889999
作者: taofan712    时间: 2017-2-9 12:31

回复 2# B魔方大人

以中国手机号为标准 ,固定11位。因为需要从各个杂乱文本中提取手机号码,组成www.bathome.com\sub\13344445555这样的网址,所以我想先把它取出来单独保存。
另外 13555557777 这个号码你没提取到。
作者: 523066680    时间: 2017-2-9 12:44

perl
  1. $all = `type src.txt`;
  2. $all =~ s/\r?\n//g;
  3. while ($all=~s/[^\d]?(\d{11})[^\d]?//)
  4. {
  5.     print "$1\n";
  6. }
复制代码

作者: taofan712    时间: 2017-2-9 13:52

回复 4# 523066680
谢谢版主,请问有批处理方案吗?
新人刚开始学【绝非伸手党】,有个大概思路:
  1. @echo off
  2. echo on
  3. setlocal enabledelayedexpansion
  4. for %%a in (134 135 136 137 138 139 150 151 152 158 159 157 182 187 188 147  130 131 132 155 156  185 186   133 153  180 189) do (set 3a=%%a
  5. for /f "delims=!3a! tokens=1*" %%b  in ('type a.txt^|find "!3a!"') do (
  6. rem 我这个只能查到第一个出现数字的地方,这个delims和tokens要怎么写才能把每一行的所有数字都查到呢
  7. set 8b=%%c
  8. set "8b=!8b:~0,8!"
  9. rem 这里判断变量8b是否全部是数字 if "!8b!"==(全部是数字)
  10. echo,!3a!!8b!>>phnum.txt
  11. )
  12. )
  13. pause>nul
复制代码

作者: 老刘1号    时间: 2017-2-9 14:44

本帖最后由 老刘1号 于 2017-2-9 15:10 编辑
  1. '&wscript  -nologo -e:vbscript "%~0"
  2. text=_
  3. "寒蝉凄13切,对长亭晚,13311111111骤雨初歇。"&vbcrlf&_
  4. "都门帐饮无绪,留恋处舟催发。执手相看[color=Red]1355555"&vbcrlf&_
  5. "7777[/color]泪眼,竟无语凝噎。念15去135去千里烟波,"&vbcrlf&_
  6. "暮霭沉1314沉楚天阔。  多情自古12580伤离别,"&vbcrlf&_
  7. "更那堪冷落清秋节。今宵酒醒何处?136杨柳岸晓风10010残月。"&vbcrlf&_
  8. "1372222此444去经年,应是良辰好景虚设。"&vbcrlf&_
  9. "便纵10086有千种风情,更与何人说? 13788889999"
  10. Function RegExpTest(patrn, strng)
  11.    Dim regEx, Match, Matches   ' 建立变量。
  12.    Set regEx = New RegExp   ' 建立正则表达式。
  13.    regEx.Pattern = patrn   ' 设置模式。
  14.    regEx.Global = True   ' 设置全局可用性。
  15.    regEx.IgnoreCase = True   ' 设置是否区分字符大小写。
  16.    Set Matches = regEx.Execute(strng)   ' 执行搜索。
  17.    For Each Match in Matches   ' 遍历匹配集合。
  18.       RetStr = RetStr & Match.Value& vbCRLF
  19.    Next
  20.    RegExpTest = RetStr
  21. End Function
  22.                         MsgBox(RegExpTest("1\d{10}", text))
复制代码
保存为CMD、BAT、VBS、VBE随意
作者: B魔方大人    时间: 2017-2-9 15:26

本帖最后由 B魔方大人 于 2017-2-9 15:28 编辑

bat.
  1. 1>1/* :
  2. (@cscript -nologo -e:jscript %0<0.txt)>1.txt&exit
  3. */
  4. var c = WSH.StdIn.ReadAll().replace(/.\r\n/g).match(/1[34578]\d{9}/g);
  5. WSH.ECHO(c);
复制代码

作者: zz100001    时间: 2017-2-9 15:39

本帖最后由 zz100001 于 2017-2-9 15:47 编辑

诉我直言,很多人已经不喜欢用批处理了
字符处理不好也不方便
于是给你的一般都是ps或者“混编批处理”(其实就是拿批处理启动其他脚本
电话号码如何识别你也没有明确的标准
这里就按11位数字来取好了
  1. @echo off
  2. set fn=a.txt
  3. setlocal enabledelayedexpansion
  4. set PhoneNumbers=
  5. set pn=
  6. set /a nc=0
  7. call :PhoneNumberReader "%fn%"
  8. echo 文件中包含的全部手机号:
  9. echo %PhoneNumbers%
  10. pause
  11. goto :EOF
  12. :PhoneNumberReader
  13. echo %~s1
  14. for /f "delims=" %%a in (%~s1) do (
  15.     call :CharReader %%a
  16. )
  17. call :CheckPhoneNumber
  18. goto :EOF
  19. :CharReader
  20. set l=%*
  21. :CheckNumber
  22. set /a n=!l:~,1! 1>nul 2>&1
  23. if "!n!" equ "!l:~,1!" (
  24.     set pn=!pn!!n!
  25.     set /a nc+=1 1>nul 2>&1
  26. ) else (
  27.     call :CheckPhoneNumber *
  28. )
  29. set l=!l:~1!
  30. if "!l!" neq "" goto :CheckNumber
  31. goto :EOF
  32. :CheckPhoneNumber
  33. if !nc! equ 11 (
  34.     for %%a in (134 135 136 137 138 139 150 151 152 158 159 157 182 187 188 147 130 131 132 155 156 185 186 133 153 180 189) do (
  35.         if "%%a" equ "!pn:~,3!" (
  36.             echo 找到一个手机号:!pn!
  37.             set PhoneNumbers=!PhoneNumbers!!pn!%1
  38.             goto :CheckPhoneNumberOver
  39.         )
  40.     )
  41. )
  42. :CheckPhoneNumberOver
  43. set pn=
  44. set /a nc=0 1>nul 2>&1
  45. goto :EOF
复制代码

作者: taofan712    时间: 2017-2-9 15:59

回复 6# 老刘1号
谢谢老刘
回复 7# B魔方大人
谢谢魔方大人
作者: taofan712    时间: 2017-2-9 16:05

本帖最后由 taofan712 于 2017-2-10 13:51 编辑

回复 8# zz100001

非常感谢,你的代码完美的解决了我的问题。

有点遗憾,我10年就注册了批处理之家,中途都是偶尔看看,到现在才真正开始对批处理产生浓厚兴趣。
提这个问题更直接的原因也是想从中学习批处理而不是通过其他语言手段得到这个问题的答案。
所以真的特别感谢你写这么长的代码回答我的问题。
谢谢。
——————————
看到现在,终于看懂了,逐字找出连续11位数字,再对比前3位。
作者: 回家路上    时间: 2017-2-9 16:24

注定goto多次,注定慢... ...
  1. @echo off & setlocal enabledelayedexpansion
  2. :: 逐个字符找【11位,以1[34578]开头】的数字
  3. for /f "delims=" %%i in ('type 1.txt') do (
  4. call :split "%%i"
  5. )
  6. pause & exit /b
  7. :: ------------------------------------------
  8. :split [line]
  9. if not defined line set line=%~1
  10. set n=!line:~,1!
  11. if not defined n goto :eof
  12. if !n! leq 9 (
  13. if !n! geq 0 (
  14. set _num=1
  15. )
  16. )
  17. if defined _num (
  18. set "_num="
  19. set num=!num!!n!
  20. ) else set "num="
  21. if "!num!" neq "" if "!num:~10!" neq "" (
  22. set _legal=
  23. if "!num:~,1!"=="1" (
  24. for %%i in (3,4,5,7,8) do (
  25. if not defined _legal (
  26. if "!num:~1,1!"=="%%i" set _legal=1
  27. )
  28. )
  29. )
  30. if defined _legal (
  31. echo;!num!& set "num="
  32. ) else set num=!num:~1!
  33. )
  34. set line=!line:~1!
  35. if "!line!" neq "" goto :split
  36. goto :eof
复制代码

作者: taofan712    时间: 2017-2-9 16:42

本帖最后由 taofan712 于 2017-2-10 13:49 编辑

回复 11# 回家路上

谢谢,你冷酷的言语下有火热的心啊,哈哈。我把你和zz100001的代码都保存下来慢慢看。没看完之前不提新问题了。



看了一天多了,到现在才看明白过程是怎样的再次感谢。另外,从这里的代码我突然明白“从上到下一直写到底更适合菜鸟阅读”这句话是错误的……
作者: codegay    时间: 2017-2-9 16:46

先findstr把有电话号码的行取出来啊。
作者: GNU    时间: 2017-2-9 16:52

本帖最后由 GNU 于 2017-2-9 16:53 编辑
  1. grep -Pow "\d{11}" "1.txt" > "2.txt"
复制代码
grep.exe 2.22 测试通过
http://bbs.bathome.net/s/tool/index.html?key=grep
作者: codegay    时间: 2017-2-9 17:20

sed awk poweshell之类的应该就一行。
作者: 回家路上    时间: 2017-2-9 17:41

JS,存为.bat运行
  1. @set @n=0; /* & echo off & type 1.txt|cscript -nologo -e:jscript "%~f0" & pause & exit/b & rem */
  2. WScript.StdIn.ReadAll()
  3. .replace(/\s/g, "")
  4. .replace(/(1[34578]\d{9})/g, function(a,b){
  5. WScript.Echo(b);
  6. });
复制代码

作者: terse    时间: 2017-2-12 20:39

  1. @echo off
  2. set /an=Len=0
  3. for /f "delims=" %%i in ('findstr /r "1[3-58][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"^<1.txt') do (
  4.     set "s=%%i"
  5.     set "str=%%i"
  6.     setlocal enabledelayedexpansion
  7.     for %%j in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
  8.         if "!s:~%%j!" neq "" set /a Len+=%%j & set "s=!s:~%%j!"
  9.     )
  10.     for /l %%j in (0,1,!len!) do (
  11.         set t=!str:~%%j,1!
  12.         if !t! leq 9 (
  13.            if !t! geq 0 (
  14.               set /a n+=1
  15.               set num=!num!!t!
  16.            ) else set num=&set "n=0"
  17.         ) else set num=&set "n=0"
  18.         if !n! equ 11 (
  19.            echo;!num!
  20.            set num=&set "n=0"
  21.         )
  22.     )
  23.     endlocal
  24. )
  25. pause
复制代码

作者: CrLf    时间: 2017-2-12 21:08

回复 17# terse


    用这个好像会省事些:
  1. findstr /r "\<1[3-58][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\>"
复制代码

作者: terse    时间: 2017-2-12 21:53

回复 18# CrLf
此类匹配不了哦
...13088889999qrweqr1391511412413088889999...





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