繁体   English   中英

批处理Windows中的正则表达式

Regex in Batch Windows

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我目前正在做一个批处理工作(也是我的新手),以获取Maven依赖项列表。 一直在使用正则表达式来获取这些依赖项,但无济于事。 我已经在此站点上测试了我的正则表达式,看来它正在运行。

从这个stackoverflow问题中检查了FOR循环中需要的转义字符,但是再次失败了,因此我不得不在这里寻求帮助。

请参见下面的我的代码段esp。 正则表达式部分,外部循环很好。

for /f "tokens=*" %%i in ('findstr "+- \\-"  dependency-list.txt') do (
    for /f "tokens=*" %%j in ('findstr /i /r "^^(.+^)\[:\]^(.+^)^(:jar:^)^(.+^)^(:compile^)" %%i') do (
        echo %%j
    )
)

这是从我的外循环中获取的示例数据:

[INFO] +- org.owasp.esapi:esapi:jar:2.0.1:compile
[INFO] |  +- commons-configuration:commons-configuration:jar:1.5:compile
[INFO] |  |  +- commons-lang:commons-lang:jar:2.3:compile

我只想使用正则表达式来获得这些部分:

commons-configuration:commons-configuration:jar:1.5:compile
org.owasp.esapi:esapi:jar:2.0.1:compile
commons-lang:commons-lang:jar:2.3:compile

这些是我尝试执行批处理脚本时遇到的错误。

FINDSTR: Cannot open org.owasp.esapi:esapi:jar:2.0.1:compile
'+-' is not recognized as an internal or external command,
operable program or batch file.
| was unexpected at this time.

任何帮助将不胜感激。

注意:一旦我能够成功执行我的正则表达式,就可以删除外部循环。

1 个回复

FINDSTR的正则表达式功能非常有限,因为可以在打开命令提示符窗口并运行findstr /?读取它findstr /? 获得帮助。 FINDSTR的正则表达式功能与Perl兼容的正则表达式Boost.Regex或Perl语法中的其他正则表达式实现相距甚远。

没有选项可用于仅通过正则表达式匹配的字符串通过FINDSTR获得输出。 有几个选项可控制FINDSTR的输出,但没有一个选项仅用于输出找到的字符串。

因此,有必要使用另一种方法dependency-list.txt文件dependency-list.txt包含+-\\-处理行上感兴趣数据的所有剩余内容。 Windows命令处理器仅提供两个用于字符串重新格式化任务的命令: FORSET

下面的批处理文件演示了这两个批处理文件,其中考虑到访问同一命令块中定义/修改的环境变量的值需要延迟扩展。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
set "DeleteExample="
if exist dependency-list.txt goto GetData
(
    set "DeleteExample=1"
    echo First line with no data of interest.
    echo [INFO] +- org.owasp.esapi:esapi:jar:2.0.1:compile
    echo [INFO] ^|  +- commons-configuration:commons-configuration:jar:1.5:compile
    echo [INFO] ^|  ^|  +- commons-lang:commons-lang:jar:2.3:compile
    echo ;[INFO]^|  \- commons-lang:commons-lang:jar:4.5:compile
    echo Line trailing space at end +- 
    echo Line with no space at end  +-
    echo Line with just a hyphen character - somewhere on line.
    echo [INFO] ^|  ^|  +- !commons-configuration!:commons-configuration!:jar:5.2:compile
    echo Last line with no data of interest.
)>dependency-list.txt

:GetData
echo First solution
echo ==============
echo/
setlocal EnableDelayedExpansion
for /F "tokens=*" %%I in ('%SystemRoot%\System32\findstr.exe /R "+- \\-" dependency-list.txt 2^>nul') do (
    echo Line read: "%%I"
    set "Line=%%I"
    set "Line=!Line:*- =!"
    if defined Line echo Line work: "!Line!"
    rem More commands working with environment variable Line referenced with
    rem exclamation marks for delayed expansion on execution of the command line.
)
endlocal

echo/
echo Second solution
echo ===============
echo/
for /F "tokens=1* delims=-" %%I in ('%SystemRoot%\System32\findstr.exe /R "+- \\-" dependency-list.txt') do (
    if not "%%J" == "" (
        echo Line read: "%%J"
        set "Line=%%J"
        setlocal EnableDelayedExpansion
        call set "Line=%%Line:~1%%"
        if defined Line call echo Line work: "%%Line%%"
        rem More commands working with environment variable Line referenced
        rem with two percent signs on both side and with using command CALL.
        endlocal
    )
)

echo/
echo Third solution
echo ==============
echo/
for /F "tokens=1* delims=-" %%I in ('%SystemRoot%\System32\findstr.exe /R "+- \\-" dependency-list.txt 2^>nul') do (
    if not "%%J" == "" (
        echo Line read: "%%J"
        for /F "tokens=*" %%L in ("%%J") do if not "%%L" == "" (
            echo Line work: "%%L"
            rem More commands working with loop variable L.
        )
    )
)

echo/
echo Fourth solution
echo ===============
echo/
for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /R "+- \\-" dependency-list.txt 2^>nul') do (
    echo Line read: "%%I"
    set "Line=%%I"
    setlocal EnableDelayedExpansion
    set "Line=!Line:*- =!"
    if defined Line echo Line work: "!Line!"
    rem More commands working with environment variable Line referenced with
    rem exclamation marks for delayed expansion on execution of the command line.
    endlocal
)

echo/
echo Fifth solution
echo ==============
echo/
for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /L /C:+- /C:"\\-" dependency-list.txt') do (
    echo Line read: "%%I"
    set "Line=%%I"
    call :ProcessLine
)
goto EndDemo

:ProcessLine
set "Line=%Line:*- =%"
if defined Line echo Line work: "%Line%"
rem More commands working with environment variable Line referenced with
rem percent signs for expansion before execution of the command line.
goto :EOF

:EndDemo
if defined DeleteExample del dependency-list.txt
echo/
endlocal
pause

该批处理文件的输出为:

First solution
==============

Line read: "[INFO] +- org.owasp.esapi:esapi:jar:2.0.1:compile"
Line work: "org.owasp.esapi:esapi:jar:2.0.1:compile"
Line read: "[INFO] |  +- commons-configuration:commons-configuration:jar:1.5:compile"
Line work: "commons-configuration:commons-configuration:jar:1.5:compile"
Line read: "[INFO] |  |  +- commons-lang:commons-lang:jar:2.3:compile"
Line work: "commons-lang:commons-lang:jar:2.3:compile"
Line read: "Line trailing space at end +- "
Line read: "Line with no space at end  +-"
Line work: "Line with no space at end  +-"
Line read: "[INFO] |  |  +- :commons-configuration:jar:5.2:compile"
Line work: ":commons-configuration:jar:5.2:compile"

Second solution
===============

Line read: " org.owasp.esapi:esapi:jar:2.0.1:compile"
Line work: "org.owasp.esapi:esapi:jar:2.0.1:compile"
Line read: " commons-configuration:commons-configuration:jar:1.5:compile"
Line work: "commons-configuration:commons-configuration:jar:1.5:compile"
Line read: " commons-lang:commons-lang:jar:2.3:compile"
Line work: "commons-lang:commons-lang:jar:2.3:compile"
Line read: " "
Line read: " !commons-configuration!:commons-configuration!:jar:5.2:compile"
Line work: "!commons-configuration!:commons-configuration!:jar:5.2:compile"

Third solution
==============

Line read: " org.owasp.esapi:esapi:jar:2.0.1:compile"
Line work: "org.owasp.esapi:esapi:jar:2.0.1:compile"
Line read: " commons-configuration:commons-configuration:jar:1.5:compile"
Line work: "commons-configuration:commons-configuration:jar:1.5:compile"
Line read: " commons-lang:commons-lang:jar:2.3:compile"
Line work: "commons-lang:commons-lang:jar:2.3:compile"
Line read: " "
Line read: " !commons-configuration!:commons-configuration!:jar:5.2:compile"
Line work: "!commons-configuration!:commons-configuration!:jar:5.2:compile"

Fourth solution
===============

Line read: "[INFO] +- org.owasp.esapi:esapi:jar:2.0.1:compile"
Line work: "org.owasp.esapi:esapi:jar:2.0.1:compile"
Line read: "[INFO] |  +- commons-configuration:commons-configuration:jar:1.5:compile"
Line work: "commons-configuration:commons-configuration:jar:1.5:compile"
Line read: "[INFO] |  |  +- commons-lang:commons-lang:jar:2.3:compile"
Line work: "commons-lang:commons-lang:jar:2.3:compile"
Line read: ";[INFO]|  \- commons-lang:commons-lang:jar:4.5:compile"
Line work: "commons-lang:commons-lang:jar:4.5:compile"
Line read: "Line trailing space at end +- "
Line read: "Line with no space at end  +-"
Line work: "Line with no space at end  +-"
Line read: "[INFO] |  |  +- !commons-configuration!:commons-configuration!:jar:5.2:compile"
Line work: "!commons-configuration!:commons-configuration!:jar:5.2:compile"

Fifth solution
==============

Line read: "[INFO] +- org.owasp.esapi:esapi:jar:2.0.1:compile"
Line work: "org.owasp.esapi:esapi:jar:2.0.1:compile"
Line read: "[INFO] |  +- commons-configuration:commons-configuration:jar:1.5:compile"
Line work: "commons-configuration:commons-configuration:jar:1.5:compile"
Line read: "[INFO] |  |  +- commons-lang:commons-lang:jar:2.3:compile"
Line work: "commons-lang:commons-lang:jar:2.3:compile"
Line read: ";[INFO]|  \- commons-lang:commons-lang:jar:4.5:compile"
Line work: "commons-lang:commons-lang:jar:4.5:compile"
Line read: "Line trailing space at end +- "
Line read: "Line with no space at end  +-"
Line work: "Line with no space at end  +-"
Line read: "[INFO] |  |  +- !commons-configuration!:commons-configuration!:jar:5.2:compile"
Line work: "!commons-configuration!:commons-configuration!:jar:5.2:compile"

前四个解决方案在以cmd.exe /C开头的单独命令进程中在后台命令行中运行:

C:\Windows\System32\findstr.exe /R "+- \\-" dependency-list.txt

此命令行导致在当前目录中搜索文件dependency-list.txt ,该目录与批处理文件的目录可能不同,使用区分大小写的正则表达式查找包含+-\\-

第五个解决方案在单独的命令进程命令行中运行:

C:\Windows\System32\findstr.exe /L /C:+- /C:"\\-" dependency-list.txt

该命令行查找相同的行,但是使用区分大小写的文字搜索来查找包含+-\\-

如果找不到任何包含+-\\-行,则FINDSTR不会向STDOUT输出任何内容,也不会向STDERR输出任何内容。

FOR将输出捕获到单独命令过程的STDOUT ,并逐行处理输出。

空行被FOR忽略,因为默认情况下,由于eol=;也以分号开头的行eol=; 是行尾字符选项的默认选项。 默认情况下, FOR使用常规空格和水平制表符作为字符串定界符,将该行拆分为子字符串(标记),并仅将第一个空格/制表符分隔的字符串分配给指定的循环变量。

第一个解决方案

第一个解决方案通过使用选项tokens=*来修改FOR的行处理行为,这将导致删除行中的所有前导空格/制表符,如果还有剩余的东西分配给行的其余部分,其中包括空格/制表符到指定的循环变量I 输出中以Line read:开头的Line read:显示了FOR进行行处理后分配给循环变量I的字符串。

该字符串分配给环境变量Line 然后,使用命令SET完成的字符串替换从行中删除直到首次出现的由连字符和空格组成的字符串,并使用延迟的环境变量扩展(根据引用在命令内部定义/修改的环境变量的值)进行操作以(开头为匹配)结束的块。

如果在字符串替换后还剩下一些东西,导致仍然定义了环境变量Line ,则使用Line work:输出该行的剩余部分Line work:以查看字符串替换的作用。

此解决方案速度很快,但缺点是FOR会忽略以分号开头的行,并且永久启用的延迟环境变量扩展会导致包含不正确处理的一个或多个感叹号的行。 但是,这是对文件dependency-list.txt的最佳解决方案, dependency-list.txt包含以;开头的感兴趣的行; 并包含一个或多个!

第二解决方案

第二种解决方案使用命令FOR将不以分号开头的每个非空行拆分为两个子字符串。 第一子串到一个或一个以上的第一次出现-被分配到指定的循环变量I和行的下一个循环变量其余J根据ASCII表。

因此,对于示例行J包含感兴趣的数据,并且在不是空字符串时带有前导空格。 再次使用SET命令将环境变量Line分配给最后一个仅从字符索引为1的第二个字符到字符串末尾的字符串,将删除前导空格。

但是,不是使用延迟扩展,而是通过引用刚刚在命令块中设置的环境变量值(两侧带有两个百分号)来使用另一种技术,并使用命令CALL强制Windows命令处理器在执行命令之前解析这两行再次SETECHO 因此,在使用CALL执行FOR两行之前解析整个命令块就变成了:

call set "Line=%Line:~1%"
if defined Line call echo Line work: %Line%

由于命令CALL导致第二次在循环的每次迭代中解析这两行,从而导致在执行setecho之前,将%Line:~1%%Line%分别替换为当前字符串,而没有第一个字符。

由于避免使用延迟扩展,因此此解决方案可以正确处理包含感叹号的目标行。

第三种解决方案

第三解决方案类似于第二解决方案。 它使用第二个FOR从外部FOR分配给分配给循环变量J的字符串中删除所有前导空格/制表符,并将剩余的字符串分配给循环变量L ,后者甚至可以是一个空字符串。

由于速度更快,该解决方案绝对比第二种解决方案更好。

第四方案

编写这四个解决方案是始终将捕获的输出中的整个非空行分配给循环变量I ,而与哪个字符是第一个字符无关。 通过定义一个空的定界符列表可以禁用行拆分行为,并且可以使用无行结束符的定义来禁用忽略以特定字符开头的行。

像在第一个解决方案中一样,删除保留为第一次出现连字符和空格的字符串。 不同之处在于,在将行分配给环境变量Line ,禁用了延迟扩展,然后仅在下一次临时启用该行以处理行字符串。

该解决方案的缺点是循环内的setlocal EnableDelayedExpansionendlocal命令的作用远不只是启用和禁用延迟扩展。 有关命令SETLOCALENDLOCAL的详细信息,请参见此 答案 因此,此解决方案绝对不是所提供解决方案中最快的解决方案。

第五解决方案

第五种解决方案与第四种解决方案相似,不同之处在于它展示了一种通用技术,该技术通过使用从FOR循环内部调用的子例程来避免在FOR循环内部处理字符串值时使用延迟扩展。

该解决方案也非常慢,但是具有一个很大的优势,即可以在批处理文件中顶部运行@echo ON时轻松调试该批处理文件。

为了了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /?
  • cls /?
  • del /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?
2 Windows批处理文件正则表达式

我有以下要求,需要在.bat文件中实现。 有人可以帮忙吗? 变量str中有一个字符串ABCD-1234 TEST SENTENCE 。 现在,我要检查字符串是否以[AZ]*-[0-9] *格式开头。 我该如何实现? 我使用FINDSTR尝试了各种正则表达式,但无法获得所需的结果 ...

3 Windows批处理正则表达式

我有一堆格式为:TOTO-A#7.wav的文件,我想将它们重命名为TOTO_7_As.wav(代表Sharp),但是我对正则表达式不是很好。 您知道是否有可能轻松做到这一点? 干杯 ...

4 正则表达式或批处理

如何使用 OR 批量编写正则表达式。 我有一个文件,我想找到“aa”或“bb”。 该文件包含以下几行: 这是我尝试过的命令: 和 任何人都可以帮助我批量使用 OR 语法来编写正则表达式。 谢谢。 ...

5 正则表达式批处理

我正在使用启用二进制操作的cmd上编写计算器。 我需要验证输入数据(删除字母和算术运算不需要的其他符号) @echo off set data= echo %* | findstr /R "\/\? ECHO" > nul IF "%ERRORLEVEL%" EQU "0" goto ...

6 Windows批处理文件中的正则表达式

我编写了一个代码,将文件从一个文件夹复制到另一个文件夹并重命名。 但是,如果FolderA中的文件夹没有F号,则不应将其复制到FolderB。 FolderA中的文件: F-1234文件名 F-2345文件名 F-3456文件名 ABC文件名 ...

7 Windows批处理文件中的正则表达式

我正在寻找一种通过批处理作业重命名多个文件的方法。 是的,我知道有许多应用程序可以实现此目的。 但是我需要一种自动化的方式,例如可以从调度程序(SOS Job Scheduler)调用的批处理文件之类的东西。 我们每天需要重命名数百个文件! 目标是在文件开头设置17-25个字符。 ...

8 批处理脚本中的正则表达式

我有 file.txt 格式的值: 任何人都有想法在脚本中打开这样的文件并将其修改为 到目前为止,我已经在记事本++中手动完成了它,但我宁愿把它放在一些脚本中,只是不知道如何: 和 ...

9 批处理正则表达式中的换行

我想将以下文本的所有行与FINDSTR / R匹配 我已经尝试过Windows FINDSTR命令的未记录功能和限制是什么? 尤其是“跨行搜索”部分。 但不幸的是,它没有用。 我的方法如下: 我想念什么吗? 还是正则表达式批处理功能不足以实现这一点? 解决方案: ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM