在findstr中使用正则表达式

44

我正在使用findstr和它的/r标志进行一些字符串验证,以允许正则表达式。特别是我想要验证整数。

正则表达式:

^[0-9][0-9]*$

对于非负数,它运行良好,但是由于我现在也支持负数,所以我尝试

^([1-9][0-9]*|0|-[1-9][0-9]*)$

适用于正数、负数或零。

这个正则表达式在理论上运行良好。我在PowerShell中测试过它,并且它匹配了我想要的内容。然而,由于

findstr /r /c:"^([1-9][0-9]*|0|-[1-9][0-9]*)$"

它不行。

虽然我知道findstr的正则表达式支持不是最先进的(甚至不如Notepad++),但我本来期望这么简单的表达式是可以工作的。

有什么想法,我在这里做错了什么吗?


给编辑的注意事项:windows标签有点多余,因为findstr只存在于Windows中... - Joey
17
Rössel说:标签的作用是帮助找到东西。在这种情况下,适度的冗余并不会有害。 - jfs
我从不会搜索像 windows 这样过度拥挤的标签;-) 但如果你认为这会有所帮助... - Joey
12
请勿忘记使用标签过滤问题。像 windowslinuxapple 这样的过度使用的标签非常方便,可以用来“忽略”这些问题。 - PA.
5个回答

65

这对我有效:

findstr /r "^[1-9][0-9]*$ ^-[1-9][0-9]*$ ^0$"

如果您不使用/c选项,则将<Strings>参数视为用空格分隔的搜索字符串列表,这使得空格成为|构造的一种粗略替代。 (只要您的正则表达式不包含空格。)


啊,你说得对。我忘了那个。是的,在正则表达式中使用空格会很糟糕,但在这里不会成为问题。 - Joey
3
我不太愿意给这种滥用正则表达式语法的问题点赞,但你解决了我的问题,谢谢!:-p - yoyo

9

啊,我应该更好地阅读文档。 原来findstr不支持交替(|)。

所以我可能需要多次调用或最终将整个内容替换为自定义解析器。

目前这就是我的做法:

set ERROR=1
rem Test for zero
echo %1|findstr /r /c:"^0$">nul 2>&1
if not errorlevel 1 set ERROR=
rem Test for positive numbers
echo %1|findstr /r /c:"^[1-9][0-9]*$">nul 2>&1
if not errorlevel 1 set ERROR=
rem Test for negative numbers
echo %1|findstr /r /c:"^-[1-9][0-9]*$">nul 2>&1
if not errorlevel 1 set ERROR=

正如Alan Moore所建议的那样,如果您的搜索字符串不包含空格,则空格字符将像“常规”正则表达式中的|一样工作 :) 如果您只是想输出包含您拥有的字符串列表的任何行。 - smartexpert
@smartexpert:您可能已经注意到Alan的答案被接受了。 - Joey

3

或者如果您可以的话,下载Windows版grep。它比findstr提供了更多功能。


这是一个纯批处理大数库。在完成基本算术后,我会选择一个适当的解析器。这也更有利于生成正确的错误消息。目前,多个 findstr 调用应该足够了。而且,如果只考虑功能,我会直接调用 PowerShell。更简单、更强大。 - Joey
1
我很好奇,为什么有人会想在批处理文件中使用大数。 - Denis Howe

1
一个更简单的正则表达式可以实现相同的功能,只需要在原始表达式的开头添加一个可选的减号:
^-?[0-9][0-9]*$

这是不正确的:它将匹配负零和带有前导零的整数,无论是正数还是负数:-001-042等,而 OP 的正则表达式则不会。此外,findstr 不支持 ? 量词,因此这个答案对 OP 的问题并不相关。 - joH1

0

Findstr正则表达式的支持相当有限。我建议使用Notepad++。其中的“在文件中查找”选项支持Perl兼容的正则表达式;匹配结果将显示文件名,行号和匹配文本,并且可以轻松复制到文本文件中。


2
Notepad++并不是非交互式脚本的一个实用选项。 - Joey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接