2010-04-10 50 views
26

我正在做一個字符串驗證,使用findstr及其/r標誌來允許正則表達式。特別是我想驗證整數。findstr中的正則表達式

正則表達式

^[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 ++這可能是一個相當成就),但我會期望這樣簡單的表達式工作。

任何想法我在做什麼錯在這裏?

+0

編者按:在* Windows *的標籤是有點多餘,因爲'findstr'只存在有... – Joey 2010-04-10 15:41:01

+12

羅塞爾:標籤是有幫助尋找的東西。在這種情況下適度的冗餘不會造成傷害。 – jfs 2010-04-10 20:18:43

+0

我永遠不會搜索像* windows * ;-)這樣擁擠的標籤,但如果您認爲它會有幫助... – Joey 2010-04-10 22:44:10

回答

37

這個工作對我來說:

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

如果不使用/c選項,<Strings>參數作爲搜索字符串的空格分隔的列表,這使得空間排序粗略替換爲|構造。 (只要你的正則表達式不包含空格,那是。)

+0

啊,你是對的。那個我忘了。是的,可再生能源中的空間會很糟糕,但那不會成爲一個問題。 – Joey 2010-04-11 08:53:30

+1

我不願意爲這種正則表達式語法的濫用投票,但你解決了我的問題,謝謝你! :-P – yoyo 2012-12-12 02:32:42

8

呃,我應該更好地讀the documentationfindstr顯然不支持更改(|)。

所以我可能會回到多個調用或最終用自定義分析器替換整個事情。

這就是我現在做的事:

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= 
+0

正如Alan Moore所建議的,如果您的搜索字符串不包含空格,那麼空格字符將會像|在'常規'正則表達式:)如果你正在做的就是輸出任何包含你有字符串列表的行。 – smartexpert 2017-07-27 15:37:09

+0

@smartexpert:您可能已經注意到Alan的答案是可以接受的。 – Joey 2017-07-27 15:54:07

2

或者如果可以的話,下載grep for windows.。比findstr提供了更多的功能。

+0

這裏沒有選項。這是一個純批量bignum庫。當我完成基本算術時,我會去找一個合適的解析器。這對於正確的錯誤消息也會更好。現在多個'findstr'調用應該就足夠了。另外,如果它只是用於功能,我只是打電話給PowerShell。更容易,更強大。 – Joey 2010-04-10 15:22:59

+0

我很着迷,我知道任何人都會想要一個bat文件中的高貴。 – 2018-03-10 10:54:01

0

能實現相同的事情可能更簡單regex,只需添加一個可選的負向您的原始表達式的開始:

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

我意識到這是一個非常舊的帖子,但認爲它可能會在未來出現,所以我很快就破解了一些更高級的批處理解決方案。通常我會使用powershell,python,ruby或vbs。批處理語言的挑戰性更大,但爲什麼不呢。 :-P


     @ECHO OFF 
     REM The _Ignore_ variable ignores text turning search if needed 
     SET _Ignore_=Ignore_something_if_you_need 
     REM Set the _Debug_ variable if you want to see all the output. 
     SET _Debug_= 
     REM Save this as a batch file and test it by passing 

     REM Usage: 
     REM Example 1: 
     REM IsItTextOrIsItANumberRegxExample.bat 123 
     REM Results:Found Number:"123" 

     REM Example 2: 
     REM IsItTextOrIsItANumberRegxExample.bat Michael123 
     REM Results:Found Number:"Michael123" 

     CALL:--CheckString %1 
     GOTO :Done 

     :--CheckString 
     SET __CheckString__=%~1 
     SET _RETURN_LETTERS_="" 
     SET _RETURN_NUMBERS_="" 
     REM Using EnableDelayedExpansion to more completely Expand the for loop results and pack in the results. 
     SETLOCAL ENABLEDELAYEDEXPANSION 
     FOR /F "tokens=1*" %%A IN ('Echo %__CheckString__%^|findstr /r "^[1-9][0-9]*$ ^-[1-9][0-9]*$ ^0$"') DO (
      IF DEFINED _Debug_ ECHO Debug:%%A 
      If %ERRORLEVEL% EQU 0 (
       IF NOT "%%A"=="%_Ignore_%" (
        IF NOT "%%A"==" " (
         SET __ReturnNumber__=%%A 
         SET __ReturnNumber__=!__ReturnNumber__: =! 
        ) 
       ) 
      ) 
     ) 
     ENDLOCAL && SET _RETURN_NUMBERS_=%__ReturnNumber__% 
     REM Note: SETLOCAL is used twice because sometimes variable output will add spaces when using two similar for loops. 
     SETLOCAL ENABLEDELAYEDEXPANSION 
     FOR /F "tokens=1*" %%A IN ('Echo %__CheckString__%^|findstr /r "^[a-z][A-Z]*[0-9]*"') DO (
      IF DEFINED _Debug_ ECHO DEBUG:%%A 
      If %ERRORLEVEL% EQU 0 (
       IF NOT "%%A"=="%_Ignore_%" (
        IF NOT "%%A"==" " (
         SET __ReturnLetters__=%%A 
        ) 
       ) 
      ) 
     ) 
     ENDLOCAL && SET _RETURN_LETTERS_=%__ReturnLetters__% 
     GOTO:EOF 

     :Done 
     IF DEFINED _RETURN_NUMBERS_ ECHO Found Number:"%_RETURN_NUMBERS_%" 
     IF DEFINED _RETURN_LETTERS_ ECHO Found Letters:"%_RETURN_LETTERS_%" 

     REM Cleanup: 
     SET _Ignore_= 
     SET _RETURN_NUMBERS_= 
     SET _RETURN_LETTERS_= 
     SET _Ignore_= 
     SET _Debug_= 
相關問題