在字符串中使用数字

时间:2014-01-28 16:38:17

标签: batch-file file-io sum

这是使用批处理文件的解决方案请求。我有一个包含两列的文件 - 名称字符串和数据字符串。数据字符串包含字母和数字。我想提取和总结数字。例如,数据字符串可以是C18H26ClN3O。正确的总和是49 (18+26+1+3+1)。这是化学品的分子式,请注意Cl表示单个元素和隐含值,在此示例中为1.还有其他可能的两个字母组合但没有三个字母组合。最后的O也有一个隐含值。我不是程序员,但我怀疑有一个更简单的方法来解决这个问题,而不是使用批处理文件。但是,我需要在批处理文件中执行此操作。输入数据文件如下所示:

hydroxychloroquine C18H26ClN3O  
ibuprofen C13H18O2  
crestor C44H54CaF2N6O12S2  
aspirin C9H8O4  

(每条记录是一行,回车)

输出文件如下所示:

hydroxychloroquine 49
ibuprofen 33
crestor 121
aspirin 21

3 个答案:

答案 0 :(得分:3)

@echo off

    setlocal enableextensions enabledelayedexpansion
    set "letters=a b c d e f g h i j k l m n o p q r s t u v w x y z"


    for /f "tokens=1,2 usebackq" %%a in ("chemical.txt") do (

        :: Remove the lowercase letters from string
        set "form="
        for /f %%z in ('cmd /d /q /u /c "echo %%~b" ^| more ^| findstr /v  "%letters%"') do (
            set "form=!form!%%~z"
        )

        :: Separate elements with spaces
        for %%z in (%letters%) do set "form=!form:%%z= %%z!"

        :: For each element, if it has number add , if not add 1
        set "sum=0"
        for %%z in (!form!) do (
            set "elem=%%z" & set "elem=!elem:~1!"
            if defined elem ( set /a "sum+=!elem!" ) else ( set /a "sum+=1" )
        )
        echo %%a !sum!
    )

    endlocal

答案 1 :(得分:2)

@ECHO OFF
SETLOCAL
REM (
 FOR /f "tokens=1*delims=" %%a IN (q21411489.txt) DO (
  SET "name="
  CALL :process %%a
 )
REM )>newfile.txt

GOTO :EOF

:process
SET "param=%2"
IF DEFINED param SET name=%name% %1&shift&GOTO process
SET "param=%1"
SET "name=%name:~1%"
SET /a count=0
:next
IF NOT DEFINED param ECHO %name% %count%&GOTO :EOF
FOR %%e IN (Ac Al Sb As Ba Be Bi Br Cd Ca Ce Cs Cl Cr Co Cu Dy) DO IF %%e==%param:~0,2% GOTO LTR2 
FOR %%e IN (Er Gd Ga Ge Au Hf Ho In Ir Fe La Pb Li Lu Mg Mn Hg) DO IF %%e==%param:~0,2% GOTO LTR2
FOR %%e IN (Mo Nd Ni Nb Os Pd Pt Po Pr Pm Pa Ra Re Rh Rb Ru Sm) DO IF %%e==%param:~0,2% GOTO LTR2
FOR %%e IN (Sc Se Si Ag Na Sr Ta Tc Te Tb Tl Th Tm Sn Ti Yb Zn Zr) DO IF %%e==%param:~0,2% GOTO LTR2
FOR %%e IN (B C F H I N O P K S W U V Y) DO IF %%e==%param:~0,1% GOTO LTR1
SET Count=Error AT %param%
SET "param="
GOTO next

:ltr2
SET "param=%param:~1%"
:ltr1
SET /a atoms=0
:numatoms
SET "param=%param:~1%"
FOR /l %%e IN (0,1,9) DO IF "%%e"=="%param:~0,1%" (
 SET /a atoms = (10 * atoms^) + %%e
 GOTO numatoms
)
IF %atoms%==0 SET /a atoms=1
SET /a count+=atoms
GOTO next

q21411489.txt包含您的列表。

你的第一次计算错了。应该是75,而不是49

答案 2 :(得分:2)

我喜欢MC ND的巧妙方法来迭代分子式的字符并删除小写字母。我通过在第一个内循环内构建数学公式,大大简化了算法的其余部分。现在解决方案只需要两个FOR循环而不是四个。

@echo off
setlocal enableDelayedExpansion
set "letters=a b c d e f g h i j k l m n o p q r s t u v w x y z"

for /f "tokens=1,2 usebackq" %%A in ("test.txt") do (
  set "form=0"
  for /f %%C in ('cmd /d /q /u /c "echo(%%B" ^| more ^| findstr /v "%letters%"') do (
    if %%C gtr 9 (set "form=!form!+1*") else set "form=!form!%%C"
  )
  if !form:~-1! == * set "form=!form:~0,-1!"
  set /a "atomCount=!form:1*+=1+!"
  echo %%A !atomCount!
)