我想使用批处理从变量中提供的文本中隔离特定字符串,但它似乎没有按预期工作。我可能会对正则表达式做错,或者我误解了“findstr”的工作方式。
我需要隔离的特定字符串是一个GUID(它有一个标准格式的字母数字字符,排列成以“ - ”分隔的字符组,如下所示:8-4-4-4-12)< / p>
@echo off
setlocal enabledelayedexpansion
SET str="This is a string that has a long uuid: (UUID: 359f975d-2649-4e20-b7c0-b452aaaca4b2)"
SET rx=[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}
FOR %%u IN ('FINDSTR /r "!rx!" "!str!"') DO ECHO %%u
endlocal
基本上,我需要的是将GUID存储在一个单独的变量中,以便稍后我可以使用它。如果能以不同的方式实现,我很乐意学习!
谢谢!
答案 0 :(得分:1)
@ECHO Off
SETLOCAL
SET "str=This is a string that has a long uuid: (UUID: 359f975d-2649-4e20-b7c0-b452aaaca4b2)"
:: Theoretical
SET "hn=[a-f0-9]"
SET "hn4=%hn%%hn%%hn%%hn%"
SET "hn8=%hn4%%hn4%"
SET "wrx=%hn8%-%hn4%-%hn4%-%hn4%-%hn8%%hn4%"
:again
IF NOT DEFINED str ECHO notfound&GOTO done
ECHO %str%|FINDSTR /b /r /i "%wrx%">NUL
IF ERRORLEVEL 1 (
REM did not find string
SET "str=%str:~1%"
GOTO again
)
SET "str=%str:~0,36%"
ECHO found "%str%"
:done
:: BFI method
SET "str=This is a string that has a long uuid: (UUID: 359f975d-2649-4e20-b7c0-b452aaaca4b2)"
SET "hn=[a-f0-9]"
SET "hn4=%hn%%hn%%hn%%hn%"
SET "hn8=%hn4%%hn4%"
:bfiagain
IF NOT DEFINED str ECHO notfound&GOTO donebfi
:: "regex" using brute-force and ignorance
ECHO %str:~0,9%|FINDSTR /b /i /r "%hn8%-">NUL
IF ERRORLEVEL 1 GOTO bfino
ECHO %str:~9,5%|FINDSTR /b /i /r "%hn4%-">NUL
IF ERRORLEVEL 1 GOTO bfino
ECHO %str:~14,10%|FINDSTR /b /i /r "%hn4%-%hn4%-">NUL
IF ERRORLEVEL 1 GOTO bfino
ECHO %str:~24,12%|FINDSTR /b /i /r "%hn4%%hn8%">NUL
:bfino
IF ERRORLEVEL 1 (
SET "str=%str:~1%"
GOTO bfiagain
)
SET "str=%str:~0,36%"
ECHO found "%str%"
:donebfi
GOTO :EOF
好吧,不要那么紧张......
从根本上说,findstr
实现了regex
的一小部分。它旨在在文件中找到一个字符串。
从理论上讲,您可以将[a-f0-9]
字符串组合在一起,并添加-
分隔符以用作“正则表达式”,然后查看主题字符串/b
(开始) )有这样的模式;如果没有,则关闭起始字符并重复直到找到或主题字符串为空。
注意:我相信GUID仅使用十六进制数字,而不是字母数字。 findstr
支持/i
使比较不区分大小写(缩短了单个“字符匹配”字符串)。是的 - 我知道^
可用于regex
(即使是比尔叔叔的小程序员工具集中的一个),但我更喜欢/b
。
唯一的小问题是它产生了out of memory
错误......
所以,一次喂它一小块,看起来很开心......
我没有进行进一步的测试,如果您的文本字符串包含cmd
视为特殊字符的字符,则会预测暴风雨天气 - 通常的嫌疑人,如重定向器,%
和兔子的耳朵。