iforever
Goto Top

Prüfen ob Variablen inhalt Buchstaben enthält

Hallo administrator.de!

Ich habe ein kleines Logikproblem, welches ich gerne lösen, bzw. erklärt haben möchte, sollte es so gar nicht funktionieren können :p

Ich habe eine Batch in der man verschiedene Uhrzeiten eintragen kann.
Und da man mit einem durchschnitts IQ von 10 bei den meisten Anwendern rechnen muss, möchte ich auch die Benutzereingaben überprüfen.

Die Eingabe erfolgt im Format SS:MM (07:12), einige Fehler habe ich schon abgefangen, der der mich ins grübeln bringt, ist folgender:
Ich möchte prüfen, ob Buchstaben verwendet worden sin. Sprich: "ab:cd"

Mein Coding sieht folgendermaßen aus:
- Variable "come" ist die eingetragene Zeit
- In ":come" wird diese eingetragen, daher das goto zurück

:: 03 Keine Buchstaben
for %%a in ("A=a" "B=b" "C=c" "D=d" "E=e" "F=f" "G=g" "H=h" "I=i" "J=j" "K=k" "L=l" "M=m"  
	  "N=n" "O=o" "P=p" "Q=q" "R=r" "S=s" "T=t" "U=u" "V=v" "W=w" "X=x" "Y=y" "Z=z") DO (SET "come=!come:%%~a!")  
		
for %%a in ("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"  
	  "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z") DO (  
	if "%come:~0,1%"=="%%a" (  
	                  echo Die Zeitangabe ist nicht korrekt!
		echo Fehler 03: Keine Buchstaben verwenden!
		goto :come
		)
	if "%come:~1,1%"=="%%a" (  
		echo Die Zeitangabe ist nicht korrekt!
		echo Fehler 03: Keine Buchstaben verwenden!
		goto :come
		)
	if "%come:~3,1%"=="%%a" (  
		echo Die Zeitangabe ist nicht korrekt!
		echo Fehler 03: Keine Buchstaben verwenden!
		goto :come
		)
	if "%come:~4,1%"=="%%a" (  
		echo Die Zeitangabe ist nicht korrekt!
		echo Fehler 03: Keine Buchstaben verwenden!
		goto :come
		)
	)
Mein Gedanke war es, alle Großbuchstaben in kleine zu konvertieren und dann zu prüfen, ob sich diese in meiner Variable befinden.
In den 4 FOR Prüfungen werden die jeweils 4 Stellen der Zeit (der : ausgenommen) geprüft, ob ein Buchstabe verwendet wurde.

Kann diese Konstellation aus FOR und IF überhaupt funktionieren?
Wenn ja, wo liegt mein Fehler?

Gruß und Danke im Vorraus
Chris

Content-Key: 258134

Url: https://administrator.de/contentid/258134

Ausgedruckt am: 19.03.2024 um 05:03 Uhr

Mitglied: 114757
114757 19.12.2014 aktualisiert um 19:21:43 Uhr
Goto Top
Hallo Chris,
machs doch so:
echo %come%|findstr /ir "^[0-2][0-9]:[0-5][0-9]$" && echo Uhrzeit OK || echo Uhrzeit nicht OK
Dann schlägst du mehrere Fliegen mit einer Klappe. Nun gut wenn eine Uhrzeitangabe größer als 23 in den Stunden ist das musst du noch prüfen, denke aber das solltest du dann auch selber schaffen face-wink

Gruß jodel32


p.s. Zur Info: If kennt auch den Schalter /i (steht für "insensitive") dann ist Groß- oder Kleinschreibung beim Vergleich kein Thema mehr face-wink

p.s. stell auf Powershell um, damit ist das ebenfalls ein Klacks ...
$result = Read-Host "Geben sie die Uhrzeit ein"  
if ($result -match '^([0-1][0-9]|2[0-3]):[0-5][0-9]$'){  
  Write-Host "Uhrzeit OK!"  
}Else{
  Write-Host "Uhrzeit FALSCH!"  
}
Mitglied: rubberman
rubberman 19.12.2014 um 23:28:24 Uhr
Goto Top
Hallo Chris,

jodel32 hat grundsätzlich Recht. Eigentlich suchst du nach einer Lösung um zu prüfen, ob die Eingabe ein vorgegebenes Format hat. Dass dort keine Buchstaben enthalten sein dürfen, ist nur die halbe Miete. Ebenso wenig dürfen irgendwelche anderen Zeichen, als Nummern und ein Doppelpunkt vorhanden sein oder die numerischen Teile einen bestimmten Wert über- oder unterschreiten.

Wenn man wirklich die unmöglichsten Eingaben des DAUs abfangen will, wird das in Batch tatsächlich eine Herausforderung. Dabei rede ich bspw. von Zeichen wie <>|& oder unpaarigen Anführungszeichen.

Du kannst ja mal mit folgendem Codeschnipsel gegen derartige Eingaben testen:
@echo off &setlocal
set /a "inp=0, err=0, SS=0, MM=0"  

set /p "inp=SS:MM> "  

setlocal EnableDelayedExpansion
for /f "tokens=1* delims=:" %%i in ("!inp!") do (  
  if "%%i:%%j" neq "!inp!" (endlocal &set /a "err |= 1") else endlocal  
  set "SS=1%%i"  
  set "MM=1%%j"   
)

call :checkUnsigned SS 100 123
set /a "err |= %errorlevel%"  

call :checkUnsigned MM 100 159
set /a "err |= %errorlevel%"  

if %err%==1 (echo Fehler) else echo OK
pause
exit /b


:checkUnsigned VarName Min Max
setlocal EnableDelayedExpansion
:: Test auf Ziffern (keine anderen Zeichen erlaubt).
for /f "delims=1234567890" %%i in ("!%~1!") do (endlocal &exit /b 1)  
:: Test auf gültige Zahl (alles was SET /A fehlerfrei verarbeiten kann).
2>nul set /a "dummy=!%~1!" || (endlocal &exit /b 1)  
:: Test auf Dezimalzahl (keine Oktalzahl durch vorangestellte 0).
if "!%~1!" neq "%dummy%" (endlocal &exit /b 1)  
:: Test auf Minimum
if %dummy% lss %~2 (endlocal &exit /b 1)
:: Test auf Maximum
if %dummy% gtr %~3 (endlocal &exit /b 1)

endlocal &exit /b 0
Grüße
rubberman
Mitglied: miniversum
miniversum 20.12.2014 um 10:28:13 Uhr
Goto Top
Hallo,

hier mal mein kurzer Vorschlag wie es auch zu lösen wäre:
@echo off
set /p come=Zeit:

set hh=%come:~0,2%
set dp=%come:~2,1%
set mm=%come:~3,2%

set hhout=%hh%
set /a hhout=%hh%
if [%hh%] neq [%hhout%] echo %hh% ist keine Zahl

set mmout=%mm%
set /a mmout=%mm%
if [%mm%] neq [%mmout%] echo %mm% ist keine Zahl

if [%dp%] neq [:] echo %dp% ist kein ":"  

echo [%hhout%][%dp%][%mmout%]

Gruß
...
Mitglied: rubberman
rubberman 20.12.2014 aktualisiert um 12:31:10 Uhr
Goto Top
Hallo miniversum.

Joa, geht schon, aber Chris traut seinen Usern nur einen IQ von 10 zu face-wink
Dein Script wertet Eingaben, wie
^1:22
1&:22
11:222
11:73
als perfekt in Ordnung. Dafür
01:22
als fehlerhaft, was in Ordnung sein sollte.
Fehler wie
&1:22
werden nicht abgefangen und
"1:22
stirbt einfach wegen Syntaxfehler face-smile Batch ist schon etwas speziell ...

Grüße
rubberman
Mitglied: miniversum
miniversum 20.12.2014 um 12:47:22 Uhr
Goto Top
Hallo,

Das ist halt ne schnelle Lösung.
Ich weiß ja nicht wofür es gut sein soll aber das sind dann anwendungsfällt indenen ich sowieso auf temporäre vbs scripte zurückgreigen würde. Die kannman ja in der Batch selbst erzeugen.

Gruß
...
Mitglied: rubberman
rubberman 20.12.2014 aktualisiert um 15:05:59 Uhr
Goto Top
Auch 'ne Möglichkeit.
Hier mal als Batch-JScript-Hybrid:

*.bat
@if (@a)==(@b) @end /* JScript Kommentar einleiten.

@echo off &setlocal
set /p "inp=SS:MM> " 
cscript //nologo //e:jscript "%~fs0" inp 
if errorlevel 1 (echo Fehler) else echo OK
pause
exit /b

:: Ende JScript Kommentar. */
var str = WScript.CreateObject("WScript.Shell").Environment("PROCESS")(WScript.Arguments.Item(0));  
var regex = new RegExp("^[0-2]\\d:[0-5]\\d$");  
var d = new Date("01/01/1970, " + str);  
if (
  !regex.test(str)
  || Object.prototype.toString.call(d) != "[object Date]"  
  || isNaN(d.getTime())
) {
  WScript.Quit(1);
}
WScript.Quit(0);

Batch pur läuft natürlich trotzdem schneller als solche Konstrukte face-wink

Grüße
rubberman
Mitglied: colinardo
colinardo 20.12.2014 aktualisiert um 21:23:14 Uhr
Goto Top
und noch als Ergänzung zu @114757's Powershell-Code, hier noch die Integrierung dessen in eine Batch:
@echo off
set /p come=Uhrzeit eingeben:
for /f "delims=" %%a in ('powershell -ExecutionPolicy ByPass -NoLogo -command "& {if('%come%' -match '^([0-1]\d|2[0-3]):[0-5]\d$'){echo OK}else{echo FEHLER}}"') DO @(  
  if "%%a" == "OK" (  
     echo Uhrzeit OK
  ) else (
     echo Uhrzeit FALSCH
  )
)
Dann haben wir jetzt bald alles durch, und der TO hat die Qual der Wahl face-smile

Frohes Fest *<(:--)
Grüße Uwe