Board logo

标题: [问题求助] 【已解决】PowerShell根据选择题正确答案保留题目中唯一正确选项 [打印本页]

作者: for_flr    时间: 2022-1-11 16:27     标题: 【已解决】PowerShell根据选择题正确答案保留题目中唯一正确选项

本帖最后由 for_flr 于 2022-1-17 14:26 编辑

请教论坛前辈,假设有a.txt文本内容全是选择题,每个题目中给出了正确答案。
为了方便记忆,我想在题目下一行只显示正确选项,比如:
1.  《二十四史》中篇幅最大的是哪部? ( A )
A.  《宋史》 B.  《明史》 C.  《唐史》 D.  《资治通鉴》
2.  谁根据小仲马的《茶花女》改编了同名歌剧?(B)
A.  奥斯汀 B.  威尔第 C.  福楼拜
更改为:
1.  《二十四史》中篇幅最大的是哪部? ( A )
A.  《宋史》
2.  谁根据小仲马的《茶花女》改编了同名歌剧?(B)
B.  威尔第

该怎么写代码
给出25个测试题如下
  1. 1.  《二十四史》中篇幅最大的是哪部? ( A )
  2. A.  《宋史》 B.  《明史》 C.  《唐史》 D.  《资治通鉴》
  3. 2.  谁根据小仲马的《茶花女》改编了同名歌剧?(B)
  4. A.  奥斯汀 B.  威尔第 C.  福楼拜
  5. 3.  "生存还是死亡,这是一个问题。"出自莎士比亚的哪部作品? (A)
  6. A.  《哈姆雷特》 B.  《李尔王》 C.  《麦克白》
  7. 4.  "侦探福尔摩斯"第一次出现是在下列哪部作品中: (A)
  8. A. 《血字的研究》 B. 《东方快车谋杀案》 C. 《尼罗河上的惨案》 D. 《难逃一生》
  9. 5.  李清照词中名句"寻寻觅觅,冷冷清清,凄凄惨惨戚戚"的词牌名是: (D)
  10. A. 醉花阴 B. 一剪梅 C. 如梦令 D. 声声慢
  11. 6.  泰戈尔获得诺贝尔文学奖的作品是: (A)
  12. A. 《飞鸟集》 B. 《吉檀迦利》 C. 《草叶集》 D. 《瑭璜》
  13. 7.  "破釜沉舟"讲的是历史上哪位名人的事迹(B )
  14. A.  李煜 B.  项羽 C.  贾岛 D.  李世民
  15. 8.  樱花的花期一般有几天(C)
  16. A.  5天 B.  6天 C.  7天 D.  8天
  17. 9.  在俄罗斯象征友谊的颜色是什么(A)
  18. A.  蓝色 B.  红色 C.  绿色 D.  黄色
  19. 10.  旗袍起源于我国哪个少数民族的服装 ( D)
  20. A.  傣族 B. 汉族 C.  维吾尔族 D.  满族
  21. 11.  夺得欧洲冠军杯最多的是下列哪只球队?( D)
  22. A.  曼彻斯特联队 B.  拜仁慕尼黑队 C.  AC米兰队 D.  皇家马德里队
  23. 12.  本次釜山亚运会上中国体育代表团共夺得多少枚金牌?( C)
  24. A.  145枚 B.  150枚 C.  155枚 D.  160枚
  25. 13.  乒乓球是中国的国球。你知道世界上仅有的三名获得过"大满贯"的运动员的名字吗?( D)
  26. A.  瓦尔德内尔,刘国梁,王励勤 B.  孔令辉,王励勤,金泽洙
  27. C.  瓦尔德内尔,孔令辉,刘国正 D.  瓦尔德内尔,孔令辉,刘国梁
  28. 14.  CBA联赛中获得最有价值球员称号最多的运动员是下列哪一位?(B )
  29. A.  姚明 B.  王治郅 C.  刘玉栋 D.  胡卫东
  30. 15.  "飞人"乔丹曾多少次获得NBA总冠军称号?(C )
  31. A.  4次 B.  5次 C.  6次 D.  7次
  32. 16.  我国可以发展边境贸易最多的省(区)是?(C )
  33. A. 内蒙古 B. 新疆 C. 云南 D. 西藏?
  34. 17.  下列平原中,由侵蚀作用形成的是(A )
  35. A. 东欧平原 B. 亚马孙平原
  36. C. 密西西比平原 D. 印度河--恒河平原
  37. 18.  世界上最大的区域性贸易集团是(A )
  38. A. 欧洲联盟(UN) B. 世界贸易组织(WTO)
  39. C. 石油输出国组织(OPEC) D. 东南亚国家联盟(ASEAN)
  40. 19.  大金塔、埃菲尔铁塔、比萨斜塔、吴哥窟依次位( C)
  41. A. 法国、缅甸、意大利、柬埔寨 B. 柬埔寨、法国、意大利、缅甸
  42. C. 缅甸、法国、意大利、柬埔寨 D. 缅甸、意大利、法国、柬埔寨
  43. 20.  位于云冈石窟附近的大型煤矿是( D)
  44. A. 平顶山 B. 兖州 C. 淮北 D. 大同
  45. 21.  欧盟中央银行所在地法兰克福是德国( D)
  46. A. 人口最多的城市 B. 最大的港口城市
  47. C. 最大的航空枢纽城市 D. 最大的高新技术工业中心
  48. 22.  被称为"万园之园"的我国古典园林是(A )
  49. A. 圆明园 B.  颐和园 C. 拙政园
  50. 23.  战国时期,主张人们不分贵贱等级、互爱互利,反对不义战争的思想家是(D )
  51. A. 孔子 B. 孟子 C. 老子 D. 墨子
  52. 24.  战国时期,总结前人医疗经验归纳出的四诊法,是哪位名医?(D )
  53. A. 李时珍 B. 华佗 C. 李冰 D. 扁鹊
  54. 25.  我国规模最大,内容最丰富的石窟群是:( A)
  55. A.  敦煌莫高窟 B.  龙门石窟 C.  云港石窟
复制代码

作者: flashercs    时间: 2022-1-11 18:29

本帖最后由 flashercs 于 2022-1-11 18:33 编辑
  1. $src = "ANSI.txt"
  2. $dst = "$src.log"
  3. $answers = 'ABCD'
  4. $reQuestion = [regex]"^\d+.*\(\s*([$answers])\s*\)\s*$"
  5. $stack = 0
  6. Get-Content -Path $src | ForEach-Object {
  7.   if ($stack -eq 0) {
  8.     $match = $reQuestion.Match($_)
  9.     if ($match.Success) {
  10.       $answer = $match.Groups[1].Value
  11.       $nextc = $answers[$answers.IndexOf($answer) + 1]
  12.       if ($null -eq $nextc) {
  13.         $reAnswer = "$answer.*?$"
  14.       } else {
  15.         $reAnswer = "$answer.*?(?=$nextc\.|$)"
  16.       }
  17.       $_
  18.       $stack = 1
  19.     }
  20.   } elseif ($stack -eq 1) {
  21.     if ($_ -match $reAnswer) {
  22.       $Matches[0]
  23.       $stack = 0
  24.     }
  25.   }
  26. } | Set-Content -Path $dst
复制代码

作者: for_flr    时间: 2022-1-12 10:19

本帖最后由 for_flr 于 2022-1-12 10:21 编辑

回复 2# flashercs

感谢大佬,代码完美运行,我保存下来慢慢分析学习。
另外,我自己写了一段,但是有错,请有空指导一下
  1. $questions=(gc a.txt) -match "^\d"
  2. $answers=(gc a.txt) -match "^A."
  3. #将题目和选项分开存储,但是abcd四选项分成两行的处理不了。
  4. for($l=0;$l -lt $questions.count;$l++){
  5. $right=$questions[$l].split("()",[StringSplitOptions]::RemoveEmptyEntries)[-1].trim() #获取正确答案
  6. $answer=$answers[$l].split("ABCD.",[StringSplitOptions]::RemoveEmptyEntries).trim() #四个选项分割开
  7. $questions[$l]
  8. $answer["ABCD".indexof($right)]
  9. #显示题目和唯一答案
  10. }
  11. $null=[console]::readkey()
复制代码
我的代码,11题会选到米兰队,想不明白为什么
11.  夺得欧洲冠军杯最多的是下列哪只球队?( D)
A.  曼彻斯特联队 B.  拜仁慕尼黑队 C.  AC米兰队 D.  皇家马德里队
作者: flashercs    时间: 2022-1-12 13:15

回复 3# for_flr
  1. $answer=$answers[$l].split(@('A.','B.','C.','D.'),[StringSplitOptions]::RemoveEmptyEntries).trim() #四个选项分割开
复制代码

作者: for_flr    时间: 2022-1-13 15:27

回复 2# flashercs


    sorry,看了很久,从第十三行开始始终看不明白,可以请你给一些注释吗。
作者: WHY    时间: 2022-1-13 17:59

本帖最后由 WHY 于 2022-1-13 18:03 编辑
  1. $arr = gc a.txt -ReadCount 0;
  2. $count = $arr.Count;
  3. $out = [Collections.ArrayList]@();
  4. for ( $i = 0; $i -lt $count; $i++ ){
  5.     $m = [regex]::match($arr[$i], '^\d+\..*\(\s*([A-Z])\s*\)$');  #匹配开头为数字+".",结尾为"([A-Z])"的行
  6.     if ( $m.Success ) {
  7.         $Queston = $arr[$i];                                      #整行赋值给变量 Queston
  8.         $Alph    = $m.Groups[1].Value;                            #字母A-Z赋值给 Alph
  9.     } elseIf ( Test-Path Variable:Alph ) {                        #如果变量 Alph 已定义
  10.         $m = $arr[$i] -match $Alph + '\.(?:(?![A-Z]\.).)*';       #匹配答案
  11.         if ( $m ) {
  12.             $Answer = $matches[0];                                #答案赋值给 Answer
  13.             [void]$out.Add( $Queston + "`r`n" + $Answer );        #问题和答案加入数组 out
  14.         }
  15.     }
  16. }
  17. sc b.txt -Value $out;    #输出
复制代码

作者: aloha20200628    时间: 2022-1-13 21:05

源文件a.txt中有些答案行被分成两行,如连为一行,则可用如下纯P代码搞定...
例如:
19.  大金塔、埃菲尔铁塔、比萨斜塔、吴哥窟依次位( C)
A. 法国、缅甸、意大利、柬埔寨 B. 柬埔寨、法国、意大利、缅甸
C. 缅甸、法国、意大利、柬埔寨 D. 缅甸、意大利、法国、柬埔寨
变为:
19.  大金塔、埃菲尔铁塔、比萨斜塔、吴哥窟依次位( C)
A. 法国、缅甸、意大利、柬埔寨 B. 柬埔寨、法国、意大利、缅甸 C. 缅甸、法国、意大利、柬埔寨 D. 缅甸、意大利、法国、柬埔寨

@echo off
setlocal enabledelayedexpansion
set/a n=1
(for /f "delims=" %%s in (a.txt) do (
  if !n! equ 1 (
    set "s=%%s" & set "s=!s: =!" & set "z=!s:~-2,1!" & set/a n+=1
    echo,%%s
  ) else (
    set/a n=1
    for /f "tokens=1-4 delims=ABCD. " %%1 in ("%%s") do (
      if /i !z! equ A (echo,!z!. %%1)
      if /i !z! equ B (echo,!z!. %%2)
      if /i !z! equ C (echo,!z!. %%3)
      if /i !z! equ D (echo,!z!. %%4)
    )
  )
))>a.new.txt
endlocal & exit/b
作者: for_flr    时间: 2022-1-14 16:24

回复 2# flashercs
  1.    $src = "ANSI.txt"
  2. $dst = "$src.log"
  3. $answers = 'ABCD' #四个选项
  4. $reQuestion = [regex]"^\d+.*\(\s*([$answers])\s*\)\s*$" #正则表达式,精确匹配题目行
  5. $stack = 0 #标记,确定当前为题目行还是选项答案行
  6. Get-Content -Path $src | ForEach-Object { #文本每行循环
  7.   if ($stack -eq 0) { #题目行
  8.     $match = $reQuestion.Match($_) #匹配
  9.     if ($match.Success) { #匹配
  10.       $answer = $match.Groups[1].Value #找出ABCD中的答案字母
  11.       $nextc = $answers[$answers.IndexOf($answer) + 1] #确定正确字母后面一个字母
  12.       if ($null -eq $nextc) { #答案为D
  13.         $reAnswer = "$answer.*?$" #匹配字母D.到行尾
  14.       } else { #答案不为D
  15.         $reAnswer = "$answer.*?(?=$nextc\.|$)" #匹配正确字母到后面一个字母之间
  16.       }
  17.       $_
  18.       $stack = 1 #标记,题目行结束
  19.     }
  20.   } elseif ($stack -eq 1) { #选项答案行
  21.     if ($_ -match $reAnswer) {
  22.       $Matches[0] #匹配出正确选项
  23.       $stack = 0 #标记,选项行结束
  24.     }
  25.   } #再次感谢,读懂之后觉得太严谨了,代码也可以这么美
  26. } | Set-Content -Path $dst
复制代码

作者: went    时间: 2022-1-14 18:25

  1. $str = Get-Content 'a.txt' | Out-String
  2. &{
  3.     #问题和答案汇到一行
  4.     $str -replace '\r\n(?=[ABCD])','' -split '\r\n' | foreach {
  5.         $arr = $_ -split '[ABCD]\.'                          #每个问题和答案分成单独的数组
  6.         $a = $arr[0].LastIndexOfAny(@('A','B','C','D'))      #找答案索引
  7.         if($a -ne -1){
  8.             $arr[0]                                          #输出问题
  9.             $ans = $arr[0].Substring($a,1)                   #根据答案索引取答案
  10.             $ans+'.'+$arr[[char]($ans)-[char]'A'+1]          #输出答案
  11.         }
  12.     }
  13. } | Out-File 'b.txt'
复制代码

作者: aloha20200628    时间: 2022-1-14 21:37

再打磨一下纯P老枪,对原版a.txt(不调整两行答案变一行)也拿下了...
@echo off
setlocal enabledelayedexpansion
set "ls="
(for /f "tokens=* delims= " %%s in (a.txt) do (
    set z=%%s & set "z=!z: =!" & set "z1=!z:~,1!"
    if !z1! geq 0 if !z1! leq 9 (
       if defined ls (
          for /f "tokens=1-4 delims=ABCD. " %%1 in ("!ls!") do (
             if /i !za! equ A (echo,!za!. %%1)
             if /i !za! equ B (echo,!za!. %%2)
             if /i !za! equ C (echo,!za!. %%3)
             if /i !za! equ D (echo,!za!. %%4)
          )
          set "ls="
       )
       set "za=!z:~-2,1!" & (echo,%%s)
    ) else if /i "!z1!"=="A" (set "ls=%%s") else (set "ls=!ls! %%s")
))>a.new.txt
if defined ls (
   for /f "tokens=1-4 delims=ABCD. " %%1 in ("!ls!") do (
       if /i !za! equ A (echo,!za!. %%1)
       if /i !za! equ B (echo,!za!. %%2)
       if /i !za! equ C (echo,!za!. %%3)
       if /i !za! equ D (echo,!za!. %%4)
   )>>a.new.txt
)
endlocal & exit/b




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