StringRegExp Problem

  • Hallo an alle,

    melde mich mal wieder nach langer Abstinenz =)

    Suche ein RegExp Pattern um folgende String

    N186 S1800 T3 M6 (HM - Schlichtfräser D=20,0)

    auf diesen vereinfachten Pattern zu prüfen

    *T*(*)

    In einem weiteren Schritt muss ich folgenden String aus den Matches herausziehen (im Beispiel oben wäre das):

    T3 (HM - Schlichtfräser D=20,0)

    Hinter dem T können mehrere Zahlen stehen, also zB. auch T236.

    Im großen und Ganzen wäre es dann, das T mit den angehängten Zahlen + Leerzeichen + Klammer auf, allem zwischen den Klammern und die Klammer zu.

    Ich bekomms einfach nicht hin =( RegExp ist für mich irgendwie immer noch ein Dorn im Auge... Bitte um Hilfe!!!!

    Gruß Oli

    Einmal editiert, zuletzt von oliverh (23. Oktober 2009 um 12:57)

  • ich hätts so gemacht

    [autoit]

    $input = InputBox('Eingabe', '', 'N186 S1800 T3 M6')
    $split = StringSplit( $input, ' ')
    $left = StringLeft($split[3], 1)
    if $left = 'T' Then
    MsgBox(0,'','Der Fräser ist ein Schlichtfräser')
    Else
    MsgBox(0,'','Der Fräser ist kein Schlichtfräser')
    EndIf
    $zahl = StringRight($split[3], StringLen($split[3]) - 1)
    MsgBox(0,'', $zahl)

    [/autoit]
  • Du hast mich leider falsch verstanden...

    Ich hole mal etwas weiter aus:

    Ich habe ein NC Programm in folgender Form (nur ein kleiner Ausschnitt) vorliegen:

    Code
    N182 G74 Z-1 L1
    N183 G74 x200 Y-1 L1
    N184 G7
    N185 G93 X0 Y0 Z0
    N186 S1800 T3 M6 (HM - Schlichtfraeser D=20,0)
    N187 G39 C3=1
    N188 G74 Z-1 L1

    Die einzelnen Zeilen der Datei habe ich bereits in ein Array eingelesen. Nun will ich per For Schleife jede Zeile auf den im ersten Post vereinfacht dargestellten Pattern überprüfen * T * ( * )

    Das ganze hat den Hintergrund, dass ich aus dem NC Programm eine Art Werkzeugliste rausextrahieren will, damit meine NCler das nicht mehr von Hand machen müssen.

    Jedes Werkzeug ist mit dem T<Nummer> gekennzeichnet, und hinten in der Klammer steht die Beschreibung des Werkzeugs.

    In meinem Beispiel soll dieser Teil des Strings extrahiert werden, wenn der Pattern "matched":

    T3 (HM - Schlichtfräser D=20,0)

    Hoffe jetzt wirds verständlicher...

    Gruß Oli

  • das heißt wenn in einer zeile T3 steht dann soll in der selben zeile hinten "(HM - Schlichtfraeser D=20,0)" hingeschrieben werden oder?
    und wenn T* dasteht dann soll iwas anderes hingeschrieben werden?
    seh ich das jetz richtig?

    wenn ja was für T* gibt es denn alles, wär gut wenn du ne Werkzeugliste postest

  • Leider wieder falsch ;) Ist nicht so einfach, sonst hätte ich es schon lange...

    hier noch einige Beispiele:

    Code
    NC Programm:
    
    
    N14 T59 M6 (INFRA-Taster!)
    N62 S700 T1 M6 (WP - Igelfraeser D050,0)
    N186 S1800 T3 M6 (HM - Schlichtfraeser D=20,0)
    Code
    Ausgabe:
    
    
    T59 (INFRA-Taster!)
    T1 (WP - Igelfraeser D050,0)
    T3 (HM - Schlichtfraeser D=20,0)

    Hoffe jetzt wirds verständlicher...

    Grüßle

  • [autoit]

    #include <Array.au3>
    #include <String.au3>
    $zeile="N186 S1800 T3 M6 (HM - Schlichtfraeser D=20,0)"

    [/autoit][autoit][/autoit][autoit]

    $Werkzeugnummer=_stringbetween($zeile,"T"," ")
    _arraydisplay($werkzeugnummer)
    $werkzeug=_stringbetween($zeile,"(",")")
    _arraydisplay($werkzeug)
    msgbox(0,"T"&$werkzeugnummer[0],$werkzeug[0])

    [/autoit]


    man könnte bei _stringbetween() auch im regex-modus "suchen" aber warum bei diesen einfachen Strings)

  • Also immer nach "T" suchen und alles davor abschneiden?

    [autoit]


    $string ="N62 S700 T1 M6 (WP - Igelfraeser D050,0)"
    $ret = StringTrimleft($string, StringInStr($string, "T")-1)
    MsgBox(1, "", $ret)

    [/autoit]
  • so ich hab jetz auch mal was gebastelt
    ich hoffe jetz passts

    [autoit]

    #Include <File.au3>
    Dim $txtfile
    $file = FileOpenDialog('Wo ist der Quellcode des NC Programm?', @ScriptDir, 'Alle (*.*)')
    If @error Then
    Msgbox(0,'Fehler', 'Fehler beim Einlesen der Datei')
    Else
    If Not _FileReadToArray($file, $txtfile) Then
    Msgbox(0,'Fehler', 'Fehler beim Einlesen der Datei')
    Else
    For $i = 1 To $txtfile[0]
    $split = StringSplit( $txtfile[$i], ' ')
    for $h = 1 To $split[0]
    If StringLeft($split[$h], 1) = 'T' Then
    $zahl = StringRight($split[$h], StringLen($split[$h]) - 1)
    Switch $zahl
    Case 1
    $Werkzeug = '(WP - Igelfraeser D050,0)'
    Case 3
    $Werkzeug = '(HM - Schlichtfraeser D=20,0)'
    Case 59
    $Werkzeug = '(INFRA-Taster!)'
    Case Else
    $Werkzeug = 'unbekannt'
    EndSwitch
    MsgBox(0, '', $split[$h] & ' ' & $Werkzeug)
    EndIf
    Next
    Next
    MsgBox(0, 'Info', 'Bin fertig')
    EndIf
    EndIf

    [/autoit]

    Statt der Msgbox in zeile 25 kannst dir ja anpassen wie du es weiter verarbeiten willst

  • das problem was ich an diesen StringTrim etc. Funktionen sehe ist, dass das NC Programm ja nicht nur aus den Werkzeuganweisungen besteht, sondern zwischendrin auch immer andere Anweisungen vorkommen und die Ergebnisse so auch falsch sein können (zB. sowas hier "(7: T3 2D BREITE MASS 325 FERTIG)"):

    Code
    N182 G74 Z-1 L1
    N183 G74 x200 Y-1 L1
    N184 G7
    N185 G93 X0 Y0 Z0
    N14 T59 M6 (INFRA-Taster!)
    N183 G74 x200 Y-1 L1
    N184 G7
    N186 S1800 T3 M6 (HM - Schlichtfraeser D=20,0)

    Nur mal eben so zusammengestückelt...

    Daher sollte ich die Strings vorher mit regulären Ausdrücken prüfen...

    ( * egal was ) T<Nummer (auch mehrere Zahlen) ( * egal was ) <Klammer auf> ( * egal was) <Klammer zu>

  • Meine Funktion gewinnt vielleicht keinen Schönheitspreis, ist aber schneller als Andy's Funktion.
    (spielt vielleicht eine Rolle bei größeren Listen)
    PS: Ja, in meiner Funktion werden Fehler noch nicht abgefangen und man könnte StringLen auch als konstante speichern wodurch nochmal etwas Zeit gewonnen wird ^^

    Spoiler anzeigen
    [autoit]

    $string = "N14 T59 M6 (INFRA-Taster!)"

    [/autoit] [autoit][/autoit] [autoit]

    Func Ausloesen()
    For $i=1 To StringLen($string)
    If StringMid($string,$i,1) = "T" Then
    ExitLoop
    EndIf
    Next
    $x=$i
    For $n=$i To StringLen($string)
    If StringMid($string,$n,1) = " " Then
    ExitLoop
    EndIf
    Next
    $y=$n
    For $m = $n To StringLen($string)
    If StringMid($string,$m,1) = "(" Then
    ExitLoop
    EndIf
    Next
    $z = $m
    Return StringMid($string,$x,$y-$x)&" "&StringMid($string,$z,StringLen($string)-$z+1)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,"Output",$string&@CRLF&Ausloesen())

    [/autoit]

    Wer immer nur das tut, was er bereits kann - wird auch immer nur das bleiben, was er bereits ist!

  • Ich weiß gar nicht wie die Werkzeuge heißen, daher kann ich auch nicht nach den Namen im Quellcode direkt prüfen...

    so funktionuiert das leider nicht...


    trotzdem schon mal danke an euch für eure bemühungen!!!

  • Die Funktion ist schonmal gar nicht schlecht für das herauslösen des Werkzeugs aus der anweisung, aber ich muss ja vorher schon irgendwie aussortieren, ob es sich überhaupt um eine Werkzeuganweisung im NC programm handelt oder nicht und hier ist der knackpunkt... wie gesag zwischen den werkzeuganweisungen können ja noch zig andere anweisungen vorkommen bei denen was weiß ich nur die richtung und geschwindigkeit des fräsers und so zeug angegeben wird...

    oje ich seh schon, das wird noch was...


    Hier mal mein script, wie es bisher ausschaut:

    [autoit]


    #Include <GUIConstantsEx.au3>
    #Include <Array.au3>
    #Include <File.au3>
    #NoTrayIcon
    Opt("GUIOnEventMode", 1)
    $main=GUICreate("Werkzeugliste erstellen", 350, 85)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "_GUIEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "_GUIEvents")
    $edit=GUICtrlCreateInput("", 5, 5, 340)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $search=GUICtrlCreateButton("NC Programm suchen (.txt) ...", 5, 30, 340, 25)
    GUICtrlSetOnEvent(-1, "_fileOpen")
    $go=GUICtrlCreateButton("Werkzeugliste aus NC Programm erstellen ...", 5, 55, 340, 25)
    GUICtrlSetOnEvent(-1, "_go")
    GUISetState(@SW_SHOW, $main)
    While True
    Sleep(10)
    WEnd
    Func _fileOpen()
    $filepath=FileOpenDialog("NC Programm auswählen", @DesktopDir & "\", "Text files (*.txt)", 1 + 2)
    GUICtrlSetData($edit, $filepath)
    EndFunc
    Func _go()
    Dim $lines
    Dim $matchLines
    $data=GUICtrlRead($edit)
    If $data="" Then
    MsgBox(0, "Fehler", "Bitte zuerst Datei einlesen")
    Else
    _FileReadToArray($data, $lines)
    _ArrayDisplay($lines)
    For $i=1 To UBound($lines)-1

    Next
    EndIf
    EndFunc
    Func _GUIEvents()
    Select
    Case @GUI_CtrlId = $GUI_EVENT_CLOSE
    Exit
    Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
    Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
    EndFunc ;==> _GUIEvents

    [/autoit]
  • soo probier mal das. ich hoff jetz passts endlich^^

    Spoiler anzeigen
    [autoit]

    #Include <GUIConstantsEx.au3>
    #Include <Array.au3>
    #Include <File.au3>
    #NoTrayIcon
    Opt("GUIOnEventMode", 1)
    $main=GUICreate("Werkzeugliste erstellen", 350, 85)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "_GUIEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "_GUIEvents")
    $edit=GUICtrlCreateInput("", 5, 5, 340)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $search=GUICtrlCreateButton("NC Programm suchen (.txt) ...", 5, 30, 340, 25)
    GUICtrlSetOnEvent(-1, "_fileOpen")
    $go=GUICtrlCreateButton("Werkzeugliste aus NC Programm erstellen ...", 5, 55, 340, 25)
    GUICtrlSetOnEvent(-1, "_go")
    GUISetState(@SW_SHOW, $main)
    While True
    Sleep(10)
    WEnd
    Func _fileOpen()
    $filepath=FileOpenDialog("NC Programm auswählen", @DesktopDir & "\", "Text files (*.txt)", 1 + 2)
    GUICtrlSetData($edit, $filepath)
    EndFunc
    Func _go()
    Dim $lines
    Dim $matchLines
    Dim $txtfile
    $data=GUICtrlRead($edit)
    If $data="" Then
    MsgBox(0, "Fehler", "Bitte zuerst Datei einlesen")
    Else
    If Not _FileReadToArray($data, $txtfile) Then
    Msgbox(0,'Fehler', 'Fehler beim Einlesen der Datei')
    Else
    For $i = 1 To $txtfile[0]
    $split = StringSplit( $txtfile[$i], ' ')
    for $h = 1 To $split[0]
    If StringLeft($split[$h], 1) = 'T' Then
    $zahl = StringRight($split[$h], StringLen($split[$h]) - 1)
    MsgBox(0, '', $split[$h] & ' ' & $split[$split[0]])
    ; msgbox nur als beispiel...
    ; lieber einfügen wie du die gefundenen werkzeuge ausgeben willst (textfile, array display, was auch immer...)
    EndIf
    Next
    Next
    MsgBox(0, 'Info', 'Bin fertig')
    EndIf
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GUIEvents()
    Select
    Case @GUI_CtrlId = $GUI_EVENT_CLOSE
    Exit
    Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
    Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
    EndFunc ;==> _GUIEvents

    [/autoit]
  • Spoiler anzeigen
    [autoit]

    #Include <string.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $string = "N186 S1800 T3 M6 (HM - Schlichtfräser D=20,0)"

    [/autoit] [autoit][/autoit] [autoit]

    If _StringInWildCard($string, "*T*(*)") Then
    $Klammer = _StringBetween($string, "(", ")")
    $Klammer = $Klammer[0]
    $T = StringTrimLeft($string, StringInStr($string, "T") - 1)
    $T = StringLeft($T, StringInStr($T, " "))
    MsgBox(0, "Ergebnis", $T & " (" & $Klammer & ")")
    Else
    MsgBox(0, "Fehler", "Werkzeug stimmt nicht!")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Func _StringInWildCard($sTest, $sWildCard)
    ;funkey 14.10.2009
    Local $sPattern = "^" & $sWildCard & "$" ; Muss von Anfang (^)bis Ende ($) passen
    $sPattern = StringReplace($sPattern, ".", "\.")
    $sPattern = StringReplace($sPattern, "[", "\[")
    $sPattern = StringReplace($sPattern, "]", "\]")
    $sPattern = StringReplace($sPattern, "+", "\+")
    $sPattern = StringReplace($sPattern, "*", ".*")
    $sPattern = StringReplace($sPattern, "?", ".")
    ;~ ConsoleWrite($sPattern & @CR)
    Return StringRegExp($sTest, $sPattern)
    EndFunc

    [/autoit]
  • Zitat

    das problem was ich an diesen StringTrim etc. Funktionen sehe ist, dass das NC Programm ja nicht nur aus den Werkzeuganweisungen besteht, sondern zwischendrin auch immer andere Anweisungen vorkommen und die Ergebnisse so auch falsch sein können (zB. sowas hier "(7: T3 2D BREITE MASS 325 FERTIG)"):

    ...diese Informationen wären am Anfang auch nicht schlecht gewesen....
    btw. JEDES Regex kann durch eine Kombinationen einfachster Stringfunktionen ersetzt werden, daher ist nicht die Frage ob regex oder nicht (da das Ergebnis identisch ist), sondern welche Vorgaben bestehen, damit die Suchfunktion ausschliesslich die "richtigen" Strings findet.
    Keine Frage, Regex sind extrem hilfreich für den, der sie lesen und verstehen KANN, aber das Problem sehe ich darin, daß jemand, der nicht in der Lage ist das Regex zu verstehen, in keinster Weise in der Lage ist, das Regex auf seine Bedürfnisse anzupassen. Nur "damit man eins hat" ein Regex zu verwenden halte ich für.. :wacko: ...

    Zitat

    ( * egal was ) T<Nummer (auch mehrere Zahlen) ( * egal was ) <Klammer auf> ( * egal was) <Klammer zu>

    wäre im 1. Post zu plazieren gewesen^^

  • Ihr habt mich jetzt irgendwie völlig verwirrt =)

    Hier noch mal mein Script mit Kommentaren:

    [autoit]


    #Include <GUIConstantsEx.au3>
    #Include <Array.au3>
    #Include <File.au3>
    #NoTrayIcon
    Opt("GUIOnEventMode", 1)
    $main=GUICreate("Werkzeugliste erstellen", 350, 85)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "_GUIEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "_GUIEvents")
    $edit=GUICtrlCreateInput("", 5, 5, 340)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $search=GUICtrlCreateButton("NC Programm suchen (.txt) ...", 5, 30, 340, 25)
    GUICtrlSetOnEvent(-1, "_fileOpen")
    $go=GUICtrlCreateButton("Werkzeugliste aus NC Programm erstellen ...", 5, 55, 340, 25)
    GUICtrlSetOnEvent(-1, "_go")
    GUISetState(@SW_SHOW, $main)
    While True
    Sleep(10)
    WEnd
    Func _fileOpen()
    $filepath=FileOpenDialog("NC Programm auswählen", @DesktopDir & "\", "Text files (*.txt)", 1 + 2)
    GUICtrlSetData($edit, $filepath)
    EndFunc ;==> _fileOpen
    Func _go()
    Dim $lines
    Dim $matchedLines
    $data=GUICtrlRead($edit)
    If $data="" Then
    MsgBox(0, "Fehler", "Bitte zuerst Datei auswählen")
    Else
    _FileReadToArray($data, $lines)
    For $i=1 To UBound($lines)-1
    ; !!!
    ; Hier muss ich prüfen ob der entsprechende String aus dem Array dem Werkzeug Pattern entspricht
    ; Danach soll der String entsprechend zerlegt werden und in das Array $matchedLines geschrieben werden
    ; !!!
    ; Das Array soll dann in eine neue Datei, Zeile für Zeile, reingeschrieben werden (das ist wiederum kein Problem...)
    Next
    EndIf
    EndFunc ;==> _go
    Func _GUIEvents()
    Select
    Case @GUI_CtrlId = $GUI_EVENT_CLOSE
    Exit
    Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
    Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
    EndFunc ;==> _GUIEvents

    [/autoit]

    Die Datei kann wie folgt aussehen:

    Folgende Strings wären dann richtig und kommen in ein neues Array, welches ich wiederum in eine neue Datei schreiben lasse:

    Code
    T1 (WP - IGELFRAESER D=50,0)
    T2 (TIN - SCHRUPPFRAESER D=20,0)
    T3 (HM - SCHLICHTFRAESER D=20,0)

    Puh wer da nicht kirre wird... :P

    Gruß