2010-04-10 35 views
26

Tôi đang thực hiện xác thực chuỗi nhỏ với findstr và cờ /r để cho phép biểu thức chính quy. Đặc biệt tôi muốn xác thực số nguyên.Cụm từ thông dụng trong findstr

Các regex

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

làm việc tốt cho số không âm nhưng kể từ khi tôi bây giờ hỗ trợ số âm cũng tôi đã cố gắng

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

cho một trong hai số nguyên dương hoặc âm hoặc bằng không.

Regex hoạt động tốt về mặt lý thuyết. Tôi đã thử nghiệm nó trong PowerShell và nó phù hợp với những gì tôi muốn. Tuy nhiên, với

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

thì không.

Mặc dù tôi biết rằng findstr không có hỗ trợ regex nâng cao nhất (ngay cả dưới Notepad ++ có thể là một thành tích khá), tôi đã mong đợi các biểu thức đơn giản như vậy hoạt động.

Bất kỳ ý tưởng nào tôi đang làm sai ở đây?

+0

Lưu ý cho ban biên tập: Các * cửa sổ * tag là một chút dư thừa, cho rằng 'findstr' chỉ tồn tại ở đó ... – Joey

+12

Rössel: Từ khóa sẽ ở đó để giúp tìm những thứ. Một dự phòng vừa phải không bị tổn thương trong trường hợp này. – jfs

+0

Tôi sẽ không bao giờ tìm kiếm một thẻ quá đông như * windows * ;-) nhưng nếu bạn nghĩ rằng nó sẽ giúp ... – Joey

Trả lời

37

này làm việc cho tôi:

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

Nếu bạn không sử dụng tùy chọn /c, lập luận <Strings> được coi là một dấu cách để tách của chuỗi tìm kiếm, mà làm cho không gian một loại thay thế thô cho cấu trúc |. (Chừng nào regexes của bạn không chứa khoảng trắng, đó là.)

+0

Aah, đúng vậy. Đó là một trong những tôi quên. Có, không gian trong RE sẽ là xấu, sau đó nhưng đó sẽ không là một vấn đề ở đây. – Joey

+1

Tôi miễn cưỡng bỏ phiếu như một sự lạm dụng cú pháp biểu thức chính quy, nhưng bạn đã giải quyết được vấn đề của tôi, cảm ơn bạn! :-p – yoyo

8

Argh, tôi nên đọc the documentation tốt hơn. findstr dường như không hỗ trợ các thay đổi (|).

Vì vậy, tôi có thể quay lại nhiều lần gọi hoặc thay thế toàn bộ nội dung bằng trình phân tích cú pháp tùy chỉnh sau cùng.

Đây là những gì tôi làm bây giờ:

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

Theo đề xuất của Alan Moore, nếu chuỗi tìm kiếm của bạn không chứa dấu cách, thì ký tự khoảng trắng sẽ hoạt động như | trong cụm từ thông dụng 'thông thường' :) nếu tất cả những gì bạn đang thực hiện đang tìm cách xuất ra bất kỳ dòng nào chứa danh sách các chuỗi bạn có. – smartexpert

+0

@smartexpert: Bạn có thể nhận thấy rằng câu trả lời của Alan là câu trả lời được chấp nhận. – Joey

2

Hoặc nếu bạn có thể tải grep for windows.. Nhiều tính năng hơn findstr cung cấp.

+0

Không có tùy chọn ở đây. Đây là một thư viện bignum lô thuần túy. Tôi sẽ đi cho một trình phân tích cú pháp thích hợp khi tôi làm xong với số học cơ bản. Điều này cũng sẽ tốt hơn cho các thông báo lỗi thích hợp. Hiện tại, nhiều lệnh gọi 'findstr' là đủ. Ngoài ra, nếu nó chỉ dành cho các tính năng tôi chỉ cần gọi PowerShell. Dễ dàng hơn nhiều, mạnh mẽ hơn nhiều. – Joey

+0

Tôi bị mê hoặc khi biết rằng bất cứ ai cũng muốn bignums trong một tập tin dơi. –

0

Một đơn giản regex mà đạt được điều tương tự là có thể, chỉ cần thêm một tùy chọn trừ khi bắt đầu biểu hiện ban đầu của bạn:

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

Tôi nhận ra đây là một bài đăng thực sự cũ nhưng nghĩ rằng nó có thể xuất hiện trong tương lai vì vậy tôi nhanh chóng tấn công một giải pháp hàng loạt tiên tiến hơn một chút. Thông thường tôi sẽ chỉ sử dụng PowerShell, python, ruby ​​hoặc vbs. Đó là rất nhiều thách thức trong một ngôn ngữ hàng loạt nhưng tại sao không. :-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_= 
Các vấn đề liên quan