Board logo

标题: [文本处理] 【已解决】批处理怎样读取字符串替换另外一个TXT文本中对应的字符串? [打印本页]

作者: TXTUSER    时间: 2024-10-31 21:11     标题: 【已解决】批处理怎样读取字符串替换另外一个TXT文本中对应的字符串?

本帖最后由 TXTUSER 于 2024-11-12 10:52 编辑

从《字典》TXT文本中读取字符串替换《原文》TXT文本中对应的字符串;
字典TXT
A=SIN(Y)
B=LOG(100)
C=TAN(Z)
D=COS(X)

以下N行省略...
原文TXT
AD=MAX(A,B)+MAX(C,D)

.....以下N行省略
结果的例子
AD=MAX(SIN(Y),LOG(100))+MAX(TAN(Z),COS(X))
作者: aloha20200628    时间: 2024-10-31 22:43

本帖最后由 aloha20200628 于 2024-11-1 15:10 编辑

回复 1# TXTUSER

匹配范围》原文.txt 每行可能出现的两种类型函数表达式中的一种,如下示例:
      AD=MAX(A,B)+MAX(C,D)
      XY=MIN(A,C)
  1. @echo off &setlocal enabledelayedexpansion
  2. (for /f "tokens=1-6 delims=(,)" %%a in (
  3.    'findstr /i "([a-z][a-z]*,[a-z][a-z]*)" 《原文》.txt') do (
  4.    set "s=%%a(_%%b,_%%c)" &if "%%d" neq "" set "s=!s!%%d(_%%e,_%%f)"
  5.    for /f "tokens=1-2 delims==" %%x in (
  6.       'findstr /i "%%b= %%c= %%e= %%f=" 《字典》.txt') do set "s=!s:_%%x=%%y!"
  7.    echo,!s!
  8. ))>"《原文》.new.txt" 2>nul
  9. type "《原文》.new.txt"
  10. endlocal&pause&exit/b
复制代码

作者: TXTUSER    时间: 2024-10-31 23:44

回复  TXTUSER

匹配范围》原文.txt 每行可能出现的两种类型函数表达式中的一种,如下示例:
      AD= ...
aloha20200628 发表于 2024-10-31 22:43


原文不是单一的一行,有很多行算式
AD=MAX(A,B)+MAX(C,D)
SU=DC(OE+FC)
HI=SUM(A*OE)
文本内容很多,每行都是一个算式

字典业有很多条
A=SIN(Y)
B=LOG(100)
C=TAN(Z)
D=COS(X)
OE=POW(3)
FC=SQRT(6)
以下N行省略...
请老师再优化一下
作者: qixiaobin0715    时间: 2024-11-1 09:19

本帖最后由 qixiaobin0715 于 2024-11-1 09:30 编辑

回复 1# TXTUSER
你把原文txt放到网盘上,让大家帮你参谋参谋。
举例示范规律性不强,你自己又没说清楚。
作者: TXTUSER    时间: 2024-11-1 10:24

回复 4# qixiaobin0715 提示
附件上传不成功
作者: qixiaobin0715    时间: 2024-11-1 10:41

回复 5# TXTUSER
本论坛关闭了附件上传功能,我说的是网盘
作者: aloha20200628    时间: 2024-11-1 11:08

本帖最后由 aloha20200628 于 2024-11-1 15:17 编辑

回复 3# TXTUSER

二楼代码已订正如下,可以匹配3楼的示例样本了,目前设定可匹配1-4个圆括号运算项,设定每个运算项内可匹配1-2个变量...
  1. @echo off &setlocal enabledelayedexpansion
  2. (for /f "delims=" %%s in (《原文》.txt) do (
  3.    set "s=%%s"
  4.    for /f "tokens=1-8 delims=()" %%a in ("%%s") do (
  5.       for %%i in ("%%b" "%%d" "%%f" "%%h") do (
  6.          for /f "tokens=1-2 delims=,+-/*" %%1 in ("%%~i") do (
  7.             set "v=%%1=" &if "%%2" neq "" set "v=!v! %%2="
  8.             for /f "tokens=1-2 delims==" %%x in (
  9.                'findstr /i "!v!" 《字典》.txt'
  10.             ) do set "s=!s:(%%x=(%%y!" &set "s=!s:%%x)=%%y)!")
  11.       ))
  12.    if "%%s" neq "!s!" echo,!s!
  13. ))>"《原文》.new.txt" 2>nul
  14. type "《原文》.new.txt"
  15. endlocal&pause&exit/b
复制代码

作者: Batcher    时间: 2024-11-1 12:50

回复 5# TXTUSER


如果需要上传文件,请用使用网盘。例如:
百度:https://pan.baidu.com
蓝奏:https://www.lanzou.com

如果需要上传截图,可以找个图床,例如:
http://bbs.bathome.net/thread-60985-1-1.html
作者: idwma    时间: 2024-11-1 14:33

ps也来试一下
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $aaaa='字典.txt'
  3. $bbbb='原文.txt'
  4. gc $aaaa|%{$cccc=$_ -split '=';iex('$'+$cccc[0]+'="'+$cccc[1]+'"')}
  5. (gc $bbbb)|%{
  6. [regex]::replace(
  7.   $_,
  8.   '(?<=\()[^)]+(?=\))',
  9.   {
  10.    [regex]::replace(
  11.     $args[0].groups[0]-join'',
  12.     '\w+',
  13.     {iex('$'+$args[0].groups[0])}
  14.    )
  15.   }
  16. )
  17. }|sc $bbbb
复制代码

作者: Five66    时间: 2024-11-1 16:53

啊 ,这要想准确 ,应该得像编译器或解析器那样对原文件进行分词(Tokenization)吧 ,自己弄挺麻烦的 ,可以弄成C宏或m4宏 ,然后用对应的宏处理器进行替换
比如下面的 ,在mingw里用gawk将字典dic.txt替换换成C宏 ,然后用C宏处理程序对原文件yuanwen.txt进行处理的输出结果

作者: TXTUSER    时间: 2024-11-5 23:32

回复  TXTUSER

二楼代码已订正如下,可以匹配3楼的示例样本了,目前设定可匹配1-4个圆括号运算项,设定 ...
aloha20200628 发表于 2024-11-1 11:08



    烦请老师参见附件优化一下例子
作者: TXTUSER    时间: 2024-11-5 23:33

本帖最后由 TXTUSER 于 2024-11-8 13:00 编辑

回复 9# idwma



       烦请老师参见附件优化一下
作者: TXTUSER    时间: 2024-11-5 23:36

回复 8# Batcher

发了网盘链接,怎么不显示啊
作者: TXTUSER    时间: 2024-11-5 23:37

本帖最后由 TXTUSER 于 2024-11-8 13:01 编辑

回复 7# aloha20200628
烦请老师参见附件优化一下
作者: qixiaobin0715    时间: 2024-11-6 08:56

本帖最后由 qixiaobin0715 于 2024-11-6 08:57 编辑

使用代码完成某个项目的处理时,需要比较清晰的逻辑为基础。根据顶楼的描述,替换字符串存在于字典文件中。楼主提供的网盘文件又有不同,替换字符串同时存在于字典文件和原文文本中,关键是代码如何判定原文文件中的字符串,哪个是需要替换的字符串,哪个又是要被替换的字符串?
作者: qixiaobin0715    时间: 2024-11-6 09:04

4楼提的要求等于没说,我的本意是在网盘 上传真实的需要处理的文件,而不是随意杜撰一些文件。
作者: TXTUSER    时间: 2024-11-6 10:15

回复 15# qixiaobin0715


    字典中的X\Y分别对应原文中的数组变量
作者: TXTUSER    时间: 2024-11-6 10:16

回复 16# qixiaobin0715
附件中的结果就是真实的需要
作者: qixiaobin0715    时间: 2024-11-6 10:26

回复 17# TXTUSER
原文中的P1是怎么回事呢?
作者: TXTUSER    时间: 2024-11-6 11:22

本帖最后由 TXTUSER 于 2024-11-8 13:01 编辑

回复 19# qixiaobin0715
老师,我重新传了附件,
这次简化了一下
请帮助解决
作者: qixiaobin0715    时间: 2024-11-6 11:36

本帖最后由 qixiaobin0715 于 2024-11-6 14:44 编辑

原来是股票啊,真搞不懂这些函数的关系。你这就不是单纯的替换了。
作者: idwma    时间: 2024-11-6 18:53

本帖最后由 idwma 于 2024-11-6 19:02 编辑

原文有两行为什么结果只留一行
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $aaaa='字典.txt'
  3. $bbbb='原文.txt'
  4. $dddd='结果.txt'
  5. $eeee=gc $bbbb
  6. gc $aaaa|%{$cccc=$_ -split '=';$eeee=$eeee -replace $cccc[0],$cccc[1]}
  7. sc $dddd $eeee
复制代码

作者: TXTUSER    时间: 2024-11-7 10:33

回复 22# idwma
结果和原文一样的,没有替换成功
作者: qixiaobin0715    时间: 2024-11-7 10:59

20楼附件处理后 DLL1(17,SIGNALS_USER(4567,2),0,0)
17、0、0这3个数是如何得到的?
作者: idwma    时间: 2024-11-7 11:02

回复 23# TXTUSER


    你举的例子和实际数据不一样,很难帮到你啊
作者: qixiaobin0715    时间: 2024-11-7 15:46

好像有点看明白了,多层嵌套式参数替换,使用批处理应当不适合,最好想想其它方法。
作者: aloha20200628    时间: 2024-11-7 15:50

本帖最后由 aloha20200628 于 2024-11-7 15:52 编辑


楼主后来提供的示例文件和要求,与开始定义的原文/字典规则出现了冲突,并加入了函数表达式整体置换的要求,如此,原文不是纯粹的原文,字典不是纯粹的字典,而且依据变量替换的顺序或依据函数表达式整体替换的顺序会导出不同的结果

作者: idwma    时间: 2024-11-8 08:57

本帖最后由 idwma 于 2024-11-8 09:06 编辑

最后一个链接失效了,只测了前面的
变量名随便输的,如果和文件里的有冲突还要改一下
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $aaaa='字典.txt'
  3. $bbbb='原文.txt'
  4. $dddd='结果.txt'
  5. gc $aaaa|?{$_ -match '='}|%{$cccc=$_ -split '=';iex('$'+$cccc[0]+'="'+$cccc[1]+'"')}
  6. $table=@{}
  7. gc $bbbb|?{$_ -match '='}|%{
  8.     $s=$_.trim()
  9.     while(
  10.         [regex]::matches($s,"\w+(?=(\((?:[^()]+|(?<Open>)\(|(?<-Open>)\))+(?(Open)(?!))\)))")|%{
  11.             $i=$_.groups[0].value+$_.groups[1].value
  12.             $table[$_.groups[0].value]=$_.groups[0].value+$_.groups[1].value
  13.             if($i -match '^\w+\([^)]+\)$'){
  14.                 $s=$s -replace [regex]::Escape($i),('$table["{0}"]' -f $_.groups[0].value)
  15.             }
  16.             1
  17.         }
  18.     ){}
  19.     while(
  20.         [regex]::matches($s,'\$\w+\[\"([^]]+)\"\]')|%{
  21.             $g=iex "$_"
  22.             $i=iex('$'+$_.groups[1])
  23.             if($i -ne $null){
  24.                 $k=$g -split '[(,)]'
  25.                 $table['c']=1
  26.                 $j=[regex]::replace(
  27.                     $i,
  28.                     '(?<=[(,])[A-Z]\w*(?=[,)])',
  29.                     {$k[$table['c']++]}
  30.                 )
  31.                 $s=$s -replace [regex]::Escape("$_"),$j
  32.                 1
  33.             }else{
  34.                 $s=$s -replace [regex]::Escape("$_"),$g
  35.                 1
  36.             }
  37.         }
  38.     ){}
  39.     $cccc=$s -split '='
  40.     iex('$'+$cccc[0]+'="'+$cccc[1]+'"')
  41.     [regex]::replace(
  42.         $s,
  43.         '(?<=[(,])\w+(?=[,)])',
  44.         {
  45.             $a=$args[0].groups[0]
  46.             if(test-path('Variable:'+$a)){iex('$'+$a)}else{$a}
  47.         }
  48.     )
  49. }|sc $dddd
复制代码

作者: TXTUSER    时间: 2024-11-8 12:34

回复 26# qixiaobin0715


    写成dll也行,麻烦老师了
作者: TXTUSER    时间: 2024-11-8 12:58

回复 28# idwma

感谢老师支持,完美解决!
作者: TXTUSER    时间: 2024-11-8 13:25

回复 28# idwma

追问老师一下,遇到下面的问题报错,如何处理?
原文增加了一行JJ=H+2 ,字典里面的H=TDXDLL1(4,0,1,0),+=TDXDLL1(35,X,Y,0)   
运行后报错
    $+=TDXDLL1(35,X,Y,0)    : 无法将“$+=TDXDLL1(35,X,Y,0)   ”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名
称的拼写,如果包括路径,请确保路径正确,然后再试一次。
所在位置 行:1 字符: 1
+ $+="TDXDLL1(35,X,Y,0)   "
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: ($+=TDXDLL1(35,X,Y,0)   :String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
作者: idwma    时间: 2024-11-9 21:56

应该可以了,有错再改
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $aaaa='字典.txt'
  3. $bbbb='原文.txt'
  4. $dddd='结果.txt'
  5. $elbat=@{}
  6. gc $aaaa|?{$_ -match '='}|%{$cccc=$_ -split '(?<=^[^=]+)=';$elbat[$cccc[0]]=$cccc[1]}
  7. $table=@{}
  8. gc $bbbb|?{$_ -match '='}|%{
  9.     $s=$_.trim()
  10.     $table['thisway']=0
  11.     while(
  12.         [regex]::matches($s,"\w+(?=(\((?:[^()]+|(?<Open>)\(|(?<-Open>)\))+(?(Open)(?!))\)))")|%{
  13.             $i=$_.groups[0].value+$_.groups[1].value
  14.             $j=$_.groups[0].value+($table['thisway']++)
  15.             $table[$j]=$_.groups[0].value+$_.groups[1].value
  16.             if($i -match '^\w+\([^)]+\)$'){
  17.                 $s=$s -replace [regex]::Escape($i),('$table["{0}"]' -f $j)
  18.             }
  19.             1
  20.         }
  21.     ){}
  22.     while(
  23.         [regex]::matches($s,'\$\w+\[\"([^]]+)\"\]')|%{
  24.             $g=iex "$_"
  25.             $i=iex('$'+$_.groups[1])
  26.             if($i -ne $null){
  27.                 $k=$g -split '[(,)]'
  28.                 $table['thisway']=1
  29.                 $j=[regex]::replace(
  30.                     $i,
  31.                     '(?<=[(,])[A-Z]\w*(?=[,)])',
  32.                     {$k[$table['thisway']++]}
  33.                 )
  34.                 $s=$s -replace [regex]::Escape("$_"),$j
  35.                 1
  36.             }else{
  37.                 $s=$s -replace [regex]::Escape("$_"),$g
  38.                 1
  39.             }
  40.         }
  41.     ){}
  42.     $cccc=$s -split '(?<=^[^=]+)='
  43.     $elbat[$cccc[0]]=$cccc[1]
  44.     [regex]::replace(
  45.         $s,
  46.         '(?<=[(,+=])\w+(?=[,)+=])',
  47.         {
  48.             $a=$args[0].groups[0].value
  49.             if($elbat[$a] -ne $null){$elbat[$a]}else{$a}
  50.         }
  51.     )
  52. }|sc $dddd
复制代码

作者: TXTUSER    时间: 2024-11-10 13:42

回复 32# idwma


   老师好,经多次测试报告如下:① 没有出现报错情况,②但是出来的结果和28楼不一致,③+号也没有被替换,请老师有空再修改一下,谢谢。
另外汉字没有被识别,乱码,改为拼音就好了
作者: idwma    时间: 2024-11-10 14:50

JJ=TDXDLL1(4,0,1,0)+2
AD=MAX(TAN(Z),COS(X))+MAX(TAN(Z),COS(X))
替换了+号应该是什么样的
作者: TXTUSER    时间: 2024-11-10 17:59

回复 34# idwma 替换规则和之前的事一样的,X,Y两个变量分别被替换为+号左右两边的字符串,具体结果如下:
JJ=TDXDLL1(35,TDXDLL1(4,0,1,0),2,0)   
AD=TDXDLL1(35,MAX(TAN(Z),COS(X)),MAX(TAN(Z),COS(X)),0)
作者: idwma    时间: 2024-11-11 00:39

乱码文件编码另存为ANSI看看
只测了这些
原文
P1=SIGNALS_USER(4567,2)
P2=REF(H,BARSLAST(P1))
JJ=H+2
AD=MAX(A,B)+MAX(C,D)
字典
H=TDXDLL1(4,0,1,0)
+=TDXDLL1(35,X,Y,0)
REF=TDXDLL1(5,X,Y,0)     
BARSLAST=TDXDLL1(17,X,0,0)
A=SIN(Y)
B=LOG(100)
C=TAN(Z)
D=COS(X)
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $aaaa='字典.txt'
  3. $bbbb='原文.txt'
  4. $dddd='结果.txt'
  5. $elbat=@{}
  6. gc $aaaa|?{$_ -match '='}|%{$cccc=$_ -split '(?<=^[^=]+)=';$elbat[$cccc[0]]=$cccc[1]}
  7. if($elbat['+'] -ne $null){$add='ADD';$elbat[$add]=$elbat['+']}
  8. $table=@{}
  9. gc $bbbb|?{$_ -match '='}|%{
  10.     $s=$_.trim()
  11.     while(
  12.         [regex]::matches($s,"\w+(?=(\((?:[^()]+|(?<Open>)\(|(?<-Open>)\))+(?(Open)(?!))\)))")|?{$_.groups[1].value -match '^\([^)]+\)$'}|%{
  13.             $l=$_.groups[1].value
  14.             $i=$_.groups[0].value+$_.groups[1].value
  15.             if($add -and $i -match '\+'){
  16.                 $l -split '[(,)]' -match '\+'|%{
  17.                     $table[$add]+=,('ADD({0})' -f ($_ -replace '\+',','))
  18.                     $l=$l -replace [regex]::Escape($_),('$table["{0}"][{1}]' -f $add,($table[$add].count-1))
  19.                 }
  20.             }
  21.             $j=$_.groups[0].value
  22.             $table[$j]+=,($j+$l)
  23.             $s=$s -replace [regex]::Escape($i),('$table["{0}"][{1}]' -f $j,($table[$j].count-1))
  24.             1
  25.         }
  26.     ){}
  27.     if($add -and $s -match '\+'){
  28.         $l=$s -split '(?<=^[^=]+)='
  29.         $table[$add]+=,('ADD({0})' -f ($l[1] -replace '\+',','))
  30.         $s=$s -replace [regex]::Escape($l[1]),('$table["{0}"][{1}]' -f $add,($table[$add].count-1))
  31.     }
  32.     while(
  33.         [regex]::matches($s,'\$\w+\[\"([^]]+)\"\]\[[^]]+\]')|%{
  34.             $g=iex "$_"
  35.             $i=$elbat[$_.groups[1].value]
  36.             if($i -ne $null){
  37.                 $k=$g -split '[(,)]'
  38.                 $table['thisway']=1
  39.                 $j=[regex]::replace(
  40.                     $i,
  41.                     '(?<=[(,])[A-Z]\w*(?=[,)])',
  42.                     {$k[$table['thisway']++]}
  43.                 )
  44.                 $s=$s -replace [regex]::Escape("$_"),$j
  45.                 1
  46.             }else{
  47.                 $s=$s -replace [regex]::Escape("$_"),$g
  48.                 1
  49.             }
  50.         }
  51.     ){}
  52.     $cccc=$s -split '(?<=^[^=]+)='
  53.     $elbat[$cccc[0]]=$cccc[1]
  54.     [regex]::replace(
  55.         $s,
  56.         '(?<=[(,+=])\w+(?=[,)+=])',
  57.         {
  58.             $a=$args[0].groups[0].value
  59.             if($elbat[$a] -ne $null){$elbat[$a]}else{$a}
  60.         }
  61.     )
  62. }|sc $dddd
复制代码

作者: TXTUSER    时间: 2024-11-11 13:50

回复 36# idwma
非常感谢老师的耐心解答,目前已经完美解决了+的问题,但是原文中同时出现了+、-、*、/,单一替换没问题,主要还是想批量替换,还请老师再增补优化一下,谢谢!
原文
P1=SIGNALS_USER(4567,2)
P2=REF(H,BARSLAST(P1))
JJ=H+2
JJ=H-2
JJ=H*2
JJ=H/2
AD=MAX(A,B)+MAX(C,D)
字典
H=TDXDLL1(4,0,1,0)
+=TDXDLL1(6,X,Y,0)
-=TDXDLL1(7,X,Y,0)
*=TDXDLL1(8,X,Y,0)
/=TDXDLL1(9,X,Y,0)
REF=TDXDLL1(5,X,Y,0)     
BARSLAST=TDXDLL1(17,X,0,0)
A=SIN(Y)
B=LOG(100)
C=TAN(Z)
D=COS(X)
作者: flashercs    时间: 2024-11-11 14:32

本帖最后由 flashercs 于 2024-11-11 17:09 编辑

回复 37# TXTUSER

原文和字典的 行注释 符是 #,注释行不处理.注释行可以删掉.
原文
  1. #行注释符#
  2. #SU=DC(OE+(FC+3))
  3. #HI=SUM(A*OE)
  4. #JJ=H+2
  5. #AD=MAX(TAN(Z),COS(X))+MAX(TAN(Z),COS(X))
  6. #P1=SIGNALS_USER(4567,2)
  7. #P2=REF(H,BARSLAST(P1))
  8. #AE=MAX(A,B)+MAX(C,D)+P2
  9. P1=SIGNALS_USER(4567,2)
  10. P2=REF(H,BARSLAST(P1))
  11. JJ=H+2
  12. JJ=H-2
  13. JJ=H*2
  14. JJ=H/2
  15. AD=MAX(A,B)+MAX(C,D)
复制代码
字典
  1. #行注释符#
  2. #A=SIN(Y)
  3. #B=LOG(100)
  4. #C=TAN(Z)
  5. #D=COS(X)
  6. #OE=POW(3)
  7. #FC=SQRT(6)
  8. #H=TDXDLL1(4,0,1,0)
  9. #+=TDXDLL1(35,X,Y,0)
  10. #REF=TDXDLL1(5,X,Y,0)+Z
  11. #BARSLAST=TDXDLL1(17,X,0,0)
  12. #*=MULTI(A1,B1)
  13. H=TDXDLL1(4,0,1,0)
  14. +=TDXDLL1(6,X,Y,0)
  15. -=TDXDLL1(7,X,Y,0)
  16. *=TDXDLL1(8,X,Y,0)
  17. /=TDXDLL1(9,X,Y,0)
  18. REF=TDXDLL1(5,X,Y,0)     
  19. BARSLAST=TDXDLL1(17,X,0,0)
  20. A=SIN(Y)
  21. B=LOG(100)
  22. C=TAN(Z)
  23. D=COS(X)
复制代码
结果
  1. #行注释符#
  2. #SU=DC(OE+(FC+3))
  3. #HI=SUM(A*OE)
  4. #JJ=H+2
  5. #AD=MAX(TAN(Z),COS(X))+MAX(TAN(Z),COS(X))
  6. #P1=SIGNALS_USER(4567,2)
  7. #P2=REF(H,BARSLAST(P1))
  8. #AE=MAX(A,B)+MAX(C,D)+P2
  9. P1=SIGNALS_USER(4567,2)
  10. P2=TDXDLL1(5,TDXDLL1(4,0,1,0),TDXDLL1(17,SIGNALS_USER(4567,2),0,0),0)
  11. JJ=TDXDLL1(6,TDXDLL1(4,0,1,0),2,0)
  12. JJ=TDXDLL1(7,TDXDLL1(4,0,1,0),2,0)
  13. JJ=TDXDLL1(8,TDXDLL1(4,0,1,0),2,0)
  14. JJ=TDXDLL1(9,TDXDLL1(4,0,1,0),2,0)
  15. AD=TDXDLL1(6,MAX(SIN(Y),LOG(100)),MAX(TAN(Z),COS(X)),0)
复制代码
保存为translate.bat,编码为ANSI
  1. <#*,:
  2. @echo off
  3. cd /d "%~dp0"
  4. set "batchfile=%~f0"
  5. Powershell -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"
  6. pause
  7. exit /b
  8. #>
  9. # 注:字典和原文的注释行开头是 #
  10. $dicFile = "字典.txt"
  11. $srcFile = "原文.txt"
  12. $dstFile = "结果.txt"
  13. $utf8 = New-Object System.Text.UTF8Encoding -ArgumentList $false
  14. $ansi = [System.Text.Encoding]::GetEncoding(0)
  15. $op_precedence = @{
  16.   '+' = 0
  17.   '-' = 0
  18.   '*' = 1
  19.   '/' = 1
  20. }
  21. $reCell = [regex]'((?>(?>\w+)\((?>[^()]+|(?<o>\()|(?<-o>\)))*\)(?(o)(?!))|\((?>[^()]+|(?<o>\()|(?<-o>\)))*\)(?(o)(?!))|\w+)+)'
  22. $reParam = [regex]'(?<=[(,])((?>(?>\w+)\((?>[^()]+|(?<o>\()|(?<-o>\)))*\)(?(o)(?!))|\((?>[^()]+|(?<o>\()|(?<-o>\)))*\)(?(o)(?!))|(?>\w+)|[^,()])+)'
  23. $dic = @{}
  24. function Resolve-TokenTree {
  25.   param([string[]]$Tokens)
  26.   if ($null -eq $Tokens -or $Tokens.Count -eq 0) { return '' }
  27.   if ($Tokens.Count -eq 1) { return $Tokens[0] }
  28.   $precedence = [int]::MaxValue
  29.   $opctr = $null
  30.   for ($i = 0; $i -lt $Tokens.Count; ++$i) {
  31.     if ($op_precedence.ContainsKey($Tokens[$i]) -and $op_precedence[$Tokens[$i]] -le $precedence ) {
  32.       $opctr = $i
  33.       $precedence = $op_precedence[$Tokens[$i]]
  34.     }
  35.   }
  36.   # Sort-Object is not stable
  37.   # $opctr = 0..($Tokens.Count - 1) | Where-Object { $op_precedence.ContainsKey($Tokens[$_]) } | Sort-Object -Property @{Expression = { $op_precedence[$Tokens[$_]] } } | Select-Object -First 1
  38.   if ($null -eq $opctr) { return $Tokens -join '' }
  39.   $dicms = @{
  40.     tokens = @(
  41.       Resolve-TokenTree $Tokens[0..($opctr - 1)]
  42.       Resolve-TokenTree $Tokens[($opctr + 1)..($Tokens.Count - 1)]
  43.     )
  44.     ctr    = 0
  45.   }
  46.   if ($dic.ContainsKey($Tokens[$opctr])) {
  47.     $token = $reParam.Replace($dic[$Tokens[$opctr]], $evaluator2)
  48.   } else {
  49.     $token = $dicms.tokens[0] + $Tokens[$opctr] + $dicms.tokens[1]
  50.   }
  51.   return $token
  52. }
  53. function Resolve-Token {
  54.   param([string]$Token)
  55.   $tokens = $reCell.Split($Token) -match '\S'
  56.   if ($tokens.Count -eq 0) { return '' }
  57.   for ($i = 0; $i -lt $tokens.Count; $i += 2) {
  58.     if ($tokens[$i] -match '^\w+$') {
  59.       if ($dic.ContainsKey($tokens[$i])) {
  60.         $tokens[$i] = Resolve-Token $dic[$tokens[$i]] # 可能变成多token
  61.       }
  62.       continue
  63.     }
  64.     if ($tokens[$i] -match '^(\w+)\((?>[^()]+|(?<o>\()|(?<-o>\)))*\)(?(o)(?!))$' -and $dic.ContainsKey($Matches[1])) {
  65.       $func = $Matches[1]
  66.       $dicms = @{
  67.         msparams = $reParam.Matches($tokens[$i])
  68.         ctr      = 0
  69.       }
  70.       $tokens[$i] = Resolve-Token $reParam.Replace($dic[$func], $evaluator3) # 可能变成多token
  71.       continue
  72.     }
  73.     $tokens[$i] = $reParam.Replace($tokens[$i], $evaluator1)
  74.   }
  75.   return Resolve-TokenTree $tokens
  76. }
  77. $evaluator1 = [System.Text.RegularExpressions.MatchEvaluator] {
  78.   param($m)
  79.   Resolve-Token $m.Value
  80. }
  81. $evaluator2 = [System.Text.RegularExpressions.MatchEvaluator] {
  82.   param($m)
  83.   if ($m.Value -match '^[A-Z]\w*$') {
  84.     $dicms.tokens[$dicms.ctr++]
  85.   } else { $m.Value }
  86. }
  87. $evaluator3 = [System.Text.RegularExpressions.MatchEvaluator] {
  88.   param($m)
  89.   if ($m.Value -match '^[A-Z]\w*$') {
  90.     $dicms.msparams[$dicms.ctr++].Value
  91.   } else { $m.Value }
  92. }
  93. foreach ($line in [IO.File]::ReadAllLines($dicFile, $ansi)) {
  94.   if ($line -notmatch '^\s*#' -and $line -match '=') {
  95.     $k, $v = $line -replace '\s+' -split '=', 2
  96.     $dic[$k] = $v
  97.   }
  98. }
  99. $lines = [IO.File]::ReadAllLines($srcFile, $ansi)
  100. for ($i = 0; $i -lt $lines.Count; $i++) {
  101.   if ($lines[$i] -notmatch '^\s*#' -and $lines[$i] -match '=') {
  102.     $lines[$i] = $lines[$i] -replace '\s+'
  103.     $k, $v = $lines[$i] -split '=', 2
  104.     $v2 = Resolve-Token $v
  105.     $dic[$k] = $v2
  106.     $lines[$i] = "${k}=${v2}"
  107.   }
  108. }
  109. $lines
  110. Set-Content -Value $lines -LiteralPath $dstFile
复制代码

作者: idwma    时间: 2024-11-11 14:57

回复 37# TXTUSER



会不会还有复合型的像JJ=H+2-H*2/H这样的
作者: czjt1234    时间: 2024-11-11 15:02

最怕甲方改需求
作者: TXTUSER    时间: 2024-11-11 15:10

回复 39# idwma


    老师考虑的很超前,这种符合形态的运算公式,能不能做?
作者: idwma    时间: 2024-11-11 15:24

回复 41# TXTUSER


JJ=H+2-H*2/H替换后的结果是什么样的
是按运算一般顺序*/优先
还是排前面的优先
作者: TXTUSER    时间: 2024-11-11 15:45

回复 42# idwma
运算符号优先
作者: idwma    时间: 2024-11-12 00:24

差点被送走
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $aaaa='字典.txt'
  3. $bbbb='原文.txt'
  4. $dddd='结果.txt'
  5. $elbat=@{}
  6. gc $aaaa|?{$_ -match '='}|%{$cccc=$_ -split '(?<=^[^=]+)=';$elbat[$cccc[0]]=$cccc[1]}
  7. $op=@{'+'='ADD';'-'='SUB';'*'='MUL';'/'='DIV'}
  8. $sa=@{}
  9. $dm=@{}
  10. $elbat.Keys -match '[+\-]'|%{$sa[$_]=$op[$_];$elbat[$op[$_]]=$elbat[$_]}
  11. $elbat.Keys -match '[*/]'|%{$dm[$_]=$op[$_];$elbat[$op[$_]]=$elbat[$_]}
  12. $exc=$op.keys -join ''
  13. $isa=$sa.keys -replace '^','\' -join ''
  14. $idm=$dm.keys -join ''
  15. $opc=@'
  16. while(
  17.     [regex]::match($l,"[^$exc,]+([$idm])[^$exc,]+")|?{$_.value -ne ''}|%{
  18.         $d=$_.groups[1].value
  19.         $table[$op[$d]]+=,('{0}({1})' -f $op[$d],($_ -replace '[*/]',','))
  20.         $l=$l -replace [regex]::Escape($_),('$table["{0}"][{1}]' -f $op[$d],($table[$op[$d]].count-1))
  21.         1
  22.     }
  23. ){}
  24. while(
  25.     [regex]::match($l,"[^$exc,]+([$isa])[^$exc,]+")|?{$_.value -ne ''}|%{
  26.         $d=$_.groups[1].value
  27.         $table[$op[$d]]+=,('{0}({1})' -f $op[$d],($_ -replace '[+-]',','))
  28.         $l=$l -replace [regex]::Escape($_),('$table["{0}"][{1}]' -f $op[$d],($table[$op[$d]].count-1))
  29.         1
  30.     }
  31. ){}
  32. '@
  33. $table=@{}
  34. gc $bbbb|?{$_ -match '='}|%{
  35.     $s=$_.trim()
  36.     while(
  37.         [regex]::matches($s,"\w+(?=(\([^()]+\)))")|%{
  38.             $l=$_.groups[1].value
  39.             $i=$_.groups[0].value+$_.groups[1].value
  40.             iex $opc
  41.             $j=$_.groups[0].value
  42.             $table[$j]+=,($j+$l)
  43.             $s=$s -replace [regex]::Escape($i),('$table["{0}"][{1}]' -f $j,($table[$j].count-1))
  44.             1
  45.         }
  46.     ){}
  47.     $l=($s -split '=')[1]
  48.     $i=$l
  49.     iex $opc
  50.     $s=$s -replace [regex]::Escape($i),$l
  51.     while(
  52.         [regex]::matches($s,'\$\w+\[\"([^]]+)\"\]\[[^]]+\]')|%{
  53.             $g=iex "$_"
  54.             $i=$elbat[$_.groups[1].value]
  55.             if($i -ne $null){
  56.                 $k=$g -split '[(,)]'
  57.                 $table['thisway']=1
  58.                 $j=[regex]::replace(
  59.                     $i,
  60.                     '(?<=[(,])[A-Z]\w*(?=[,)])',
  61.                     {$k[$table['thisway']++]}
  62.                 )
  63.                 $s=$s -replace [regex]::Escape("$_"),$j
  64.                 1
  65.             }else{
  66.                 $s=$s -replace [regex]::Escape("$_"),$g
  67.                 1
  68.             }
  69.         }
  70.     ){}
  71.     $cccc=$s -split '(?<=^[^=]+)='
  72.     $elbat[$cccc[0]]=$cccc[1]
  73.     [regex]::replace(
  74.         $s,
  75.         '(?<=[(,+=])\w+(?=[,)+=])',
  76.         {
  77.             $a=$args[0].groups[0].value
  78.             if($elbat[$a] -ne $null){$elbat[$a]}else{$a}
  79.         }
  80.     )
  81. }|sc $dddd
复制代码

作者: TXTUSER    时间: 2024-11-12 10:51

回复 44# idwma


    完美!,谢谢老师!




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