管道可变进FINDSTR W /普通防爆pressions和转义双引号 [英] Piped Variable Into FINDSTR w/ Regular Expressions and Escaped Double Quotes

查看:429
本文介绍了管道可变进FINDSTR W /普通防爆pressions和转义双引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想明白,是为了解决一个bug在一个第三方程序,而他们解决问题发给我一个批处理文件。基本上它们,以确定该字符串是否匹配运行FINDSTR定期前pression命令。如果确实如此,那么不应该被剥离出来的特殊字符被手动传递之前​​它关闭到原来的命令行程序加回。

I am trying to understand a batch file that was sent to me in order to work around a bug in a third party program while they resolve the issue. Basically they are running a findstr regular expression command in order to determine whether or not the string matches. If it does, then the special characters that should not be stripped out are being added back in manually before it is passed off to the original commandline program.

尽我所能告诉虽然,什么已经提供不工作或我不明白。我在下面粘贴code的相关部分。

As best I can tell though, what has been provided does not work or I do not understand it. I am pasting the relevant section of code below.

@echo off
setlocal
set username=%1
shift
echo %username% | findstr /r "^\"[0-9][0-9]*\"" >nul
if not errorlevel 1 (set username=";%username:~0,9%=%username:~10,4%?")
echo %username%

三块我真的有问题,有关情况如下:

The three pieces I really have questions about are as follows:


  1. 我相信经常EX $ P $上述PSS的转义间pretation是 ^[0-9] [0-9] *?这我认为意味着字符串必须的开始的数字字符,然后必须包含的零个或多个的额外的仅数字的角色为了使比赛被发现。那么,FINDSTR似乎是在做一些奇怪的转义引号,我不能让它匹配任何我都试过了。如果我删除 \\围绕 [0-9] [0-9] * 然后我就可以得到它的工作,但它不能正确拒绝非数字字符,如 123456789O1234 的输入字符串(有一个字母O代替在样本串一零)。

  2. 什么是点的> NUL

  3. 那岂不是更好地检查一个错误级别等于0,而不是不ERRORLEVEL 1,因为它可以<一href=\"http://stackoverflow.com/questions/8844868/what-are-the-undocumented-features-and-limitations-of-the-windows-findstr-comman\">possibly返回2 的错误级别?

  1. I believe the unescaped interpretation of the regular express above is ^"[0-9][0-9]*" which I think means that the string must begin with a numeric character and then must consist of zero or more additional numeric-only characters in order for a match to be found. Well, FINDSTR seems to be doing something weird with the escaped quotes and I cannot get it to match anything I have tried. If I remove the \" around [0-9][0-9]* then I can get it to work, but it does not properly reject non-numeric characters such as an input string of 123456789O1234 (there is a letter O instead of a zero in that sample string).
  2. What is the point of the >nul
  3. Wouldn't it be better to check for an errorlevel equal to 0 instead of "not errorlevel 1" since it could possibly return an error level of 2?

不管怎样,下面的code的作品,但它并不像precise如我所愿。我只是希望了解为什么在正则表达式字符串引号不工作。也许这是FINDSTR的限制,但我还没有碰到任何明确的呢。

Anyway, the following code works, but it is not as precise as I would like. I am just looking to understand why the quotes in the regex string are not working. Perhaps this is a limitation of FINDSTR, but I have not came across anything definitive yet.

@echo off
setlocal
set username=%1
shift
echo %username% | findstr /r "^[0-9][0-9]*" >nul
if not errorlevel 1 (set username=";%username:~0,9%=%username:~10,4%?")
echo %username%

我可以通过重复类14倍解决该问题,因为这是(在我的处境中的字符数<一个href=\"http://stackoverflow.com/questions/2635740/why-does-findstr-not-handle-case-properly-in-some-circumstances/8767815#8767815\">more超过15个班会导致崩溃 - 滚动至底部)。我就如何这可以更简单地实现静止好奇,当然,其余2个问题

I can workaround the problem by repeating the class 14 times since that is the number of characters in my situation (more than 15 classes will cause it to crash - scroll to the bottom). I am still curious as to how this could be achieved more simply, and of course the remaining 2 questions.

@echo off
setlocal enableDelayedExpansion
set username=%~1
shift
echo !username!|findstr /r /c:"^[0-9][0-9]*$" >nul 
if not errorlevel 1 (set username=";!username:~0,9!=!username:~10,4!?")
echo !username!

注:

  • When I first ran it after modifying my existing code to more cloesly resemble dbenham's, enableDelayedExpansion gave an error as did the quotes around setting the username (see below). I can't replicate what I did wrong, but it is all working now (this is in case someone else comes across the same issue).
  • I had tried the $ for the EOL marker (which is the key to forcing it match numeric content only), but I think that the other problems were getting in the way which made me think it was not the solution. Also, to ensure the $ works don't miss this part of dbenham's answer "...you must also make sure there are no spaces between your echoed value and the pipe symbol."
  • In short it pretty much seems that trying to put double quotes inside a regex for findstr is wrong syntax/does not work/etc... unless you are actually looking to match " in the string/files you are parsing through. See dbenham's answer for clarity here. As he noted, you can use %~1 to strip the quotes from the argument instead of adding it to your regex (and programmatically add them back in if needed).

错误消息

C:>sample.bat 123456789
'enableDelayedExpansion' is not recognized as an internal or external command,
operable program or batch file.
'"' is not recognized as an internal or external command,
operable program or batch file.
!username!

相关链接:

  • Undocumented features and limitations of the Windows FINDSTR command
  • Case sesntive anomalies with findstr (not handling case properly in some circumstances)
  • http://ss64.com/nt/findstr.html
  • http://www.robvanderwoude.com/findstr.php
  • http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/findstr.mspx

推荐答案

回答您的顺序相反的问题:

Answering your questions in reverse order:

3)如果没有ERRORLEVEL 1 可能是一样的如果%ERRORLEVEL%= = 0 ,因为如果ERRORLEVEL 1意味着如果ERRORLEVEL大于或等于1。因此,如果把ERRORLEVEL小于1。我相信FINDSTR永远不会返回负ERRORLEVEL一个不是在前面的意思,所以语法应该没问题。

3) if not errorlevel 1 is probably the same as if %errorlevel%==0 because IF ERRORLEVEL 1 means if ERRORLEVEL is greater than or equal to 1. So putting a NOT in front means if ERRORLEVEL is less than 1. I believe FINDSTR never returns a negative ERRORLEVEL, so the syntax should be OK.

2)&GT; NUL 重定向FINDSTR的标准输出输出到NUL设备,这意味着它禁止输出。通常情况下任何匹配的行会被打印出来。你只是在返回code兴趣 - 你不希望看到的输出

2) The >nul redirects the stdout output of FINDSTR to the nul device, meaning it disables the output. Normally any matching line would be printed. You are only interested in the return code - you don't want to see the output.

1)原正则表达式将匹配以报价开头的输入字符串,随后在至少一个数字,接着另一报价。它忽略了第二次报价后可能出现的任何字符。

1) The original regex will match any input string that starts with a quote, followed by at least one digit, followed by another quote. It ignores any characters that may appear after the 2nd quote.

所以下面的字符串(包括引号),将匹配:

So the following strings (quotes included) will match:


  • 0

  • 01234

  • 0

  • 01234一个

以下字符串将不匹配:


  • 0

  • 01234


  • 0A

原来的code。如果因为结束报价被剥离导致关闭)进行报价,所以脚本的其余部分失败的位数匹配的字符串数量达到一定的长度有问题。

The original code has problems if the number of digits in the matching string reaches a certain length because the ending quote gets stripped causing the closing ) to be quoted and so the rest of the script fails.

我不明白你的要求,所以我不知道如何解决的code。

I don't understand your requirements so I don't know how to fix the code.

这听起来像你不想匹配具有非数字的字符串。这意味着你需要包括行标志$在正则表达式的结尾结束。但你也必须确保有你的呼应价值和管道符号之间没有空格。

It sounds like you don't want to match strings that have non digits. That means you need to include the end of line marker $ at the end of the regex. But you must also make sure there are no spaces between your echoed value and the pipe symbol.

我相信你可能不希望在你的价值的报价,(否则你应该编程在最后添加的话)。您可以使用%〜1从提供的参数中去掉任何封闭的报价。

I believe you probably don't want quotes in your value, (or else you should programatically add them at the very end). You can use %~1 to strip any enclosing quotes from the supplied argument.

如果您正在寻找检查参数1包括什么,但数字组成的,你可以使用:

If you are looking to check if argument 1 consists of nothing but numeric digits, then you can use:

setlocal enableDelayedExpansion
set "username=%~1"
echo !username!|findstr /r "^[0-9][0-9]*$" >nul

我用延迟扩展,因为你有过在1%什么字符无法控制,如果它包含特殊字符,如&安培;或者|如果你用正常的膨胀会引起问题。我已经给了语法不是防弹的,但它处理最正常的情况。

I used delayed expansion because you have no control over what characters are in %1, and if it contains special characters like & or | it will cause problems if you use normal expansion. The syntax I have given is not bullet proof, but it handles most "normal" situations.

这是没有必要你的情况,但我preFER使用/ c选项,以防万一您的搜索字符串包含空格。所以上面可以写成

It is not necessary in your case, but I prefer to use the /c option, just in case your search string contains spaces. So the above could be written as

echo !username!|findstr /r /c:"^[0-9][0-9]*$" >nul

这似乎很奇怪,我认为原始和修改后的code只是简单地通过用户名,如果它不符合您的正则表达式。也许这就是你的意图,也许不是。

It seems odd to me that both the original and your modified code simply pass through the username if it does not match your regex. Maybe that is your intent, maybe not.

这篇关于管道可变进FINDSTR W /普通防爆pressions和转义双引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆