簡體   English   中英

管道變量到FINDSTR w /正則表達式和Escaped雙引號

[英]Piped Variable Into FINDSTR w/ Regular Expressions and Escaped Double Quotes

我正在嘗試了解發送給我的批處理文件,以便在解決問題時解決第三方程序中的錯誤。 基本上,它們正在運行findstr正則表達式命令,以確定字符串是否匹配。 如果是這樣,那么不應該被刪除的特殊字符在被傳遞到原始命令行程序之前被手動添加回來。

盡管如此,我可以說,提供的內容不起作用或者我不理解。 我正在粘貼以下代碼的相關部分。

@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%

我真正有疑問的三件如下:

  1. 我相信上面常規表達的未轉義解釋是^"[0-9][0-9]*" ,我認為這意味着字符串必須以數字字符開頭 ,然后必須由零個或多個附加數字組成字符以便找到匹配項。 好吧,FINDSTR似乎對逃脫的引號做了一些奇怪的事情,我無法讓它與我嘗試的任何東西相匹配。 如果我刪除了\\"大約[0-9][0-9]*然后我可以讓它工作,但它沒有正確拒絕非數字字符,如輸入字符串123456789O1234 (有一個字母O而不是該樣本字符串中的零值)。
  2. >nul的重點是什么?
  3. 檢查錯誤級別等於0而不是“not errorlevel 1”不是更好,因為它可能會返回錯誤級別2嗎?

無論如何,下面的代碼可以工作,但它並不像我想的那樣精確。 我只是想了解為什么正則表達式字符串中的引號不起作用。 也許這是FINDSTR的限制,但我還沒有看到任何確定的東西。

@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次來解決問題,因為這是我的情況下的字符數( 超過15個類將導致它崩潰 - 滾動到底部)。 我仍然很好奇如何更簡單地實現這一目標,當然還有剩下的兩個問題。

編輯/工作解決方案

@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!

筆記:

  • 當我在修改現有代碼之后第一次運行它時,更像是dbenham的代碼, enableDelayedExpansion給出了一個錯誤,就像設置用戶名的引號一樣(見下文)。 我不能復制我做錯了什么,但它現在都在工作(這是以防其他人遇到同樣的問題)。
  • 我曾經嘗試過EOL標記的$ (這是強制它只與數字內容匹配的關鍵),但我認為其他問題正在妨礙我認為它不是解決方案。 此外,為確保$ works的作品不要錯過dbenham的答案“......你還必須確保你的回音​​值和管道符號之間沒有空格。”
  • 簡而言之,似乎試圖將雙引號放在一個正則表達式中的findstr是錯誤的語法/不起作用/等等...除非你實際上想要匹配“你正在解析的字符串/文件。請參閱dbenham的答案為了清楚起見。正如他所指出的,您可以使用%~1來從參數中去除引號,而不是將其添加到正則表達式中(並在需要時以編程方式將它們添加回來)。

錯誤信息

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!

參考鏈接:

以相反的順序回答您的問題:

3) if not errorlevel 1可能與if %errorlevel%==0相同,因為IF ERRORLEVEL 1表示ERRORLEVEL大於或等於1.因此將NOT置於前面意味着ERRORLEVEL是否小於1.我相信FINDSTR永遠不會返回負ERRORLEVEL,因此語法應該沒問題。

2) >nul將FINDSTR的stdout輸出重定向到nul設備,這意味着它禁用輸出。 通常會打印任何匹配的行。 您只對返回代碼感興趣 - 您不希望看到輸出。

1)原始正則表達式將匹配以引號開頭的任何輸入字符串,后跟至少一個數字,然后是另一個引號。 它會忽略第二個引用后可能出現的任何字符。

因此,以下字符串(包括引號)將匹配:

  • “0”
  • “01234”
  • “0”
  • “01234”一個

以下字符串不匹配:

  • 0
  • 01234
  • “”
  • “0A”

如果匹配字符串中的數字位數達到一定長度,則原始代碼會出現問題,因為結尾引用會被剝離,從而導致結束),因此腳本的其余部分將失敗。

我不明白你的要求,所以我不知道如何修復代碼。

聽起來你不想匹配非數字字符串。 這意味着您需要在正則表達式的末尾包含行結束標記$。 但是,您還必須確保回顯值和管道符號之間沒有空格。

我相信你可能不希望你的價值引用,(或者你應該以編程的方式在最后添加它們)。 您可以使用%~1從提供的參數中去除任何封閉引號。

如果您要檢查參數1是否只包含數字,那么您可以使用:

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

我使用延遲擴展,因為您無法控制%1中的字符,以及它是否包含特殊字符,如&或| 如果使用正常擴展,它將導致問題。 我給出的語法不是防彈,但它處理大多數“正常”情況。

在您的情況下沒有必要,但我更喜歡使用/ c選項,以防您的搜索字符串包含空格。 所以上面的內容可以寫成

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

對我來說,如果它與你的正則表達式不匹配,原始代碼和修改后的代碼都只是通過用戶名,這似乎很奇怪。 也許這是你的意圖,也許不是。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM