| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY WIRD VON NVIDIA ZUM HÄNDLER DES JAHRES GEWÄHLT, eine Pressemitteilung
|
Autor
|
Thema: String auf mehrere strings durch definierte trennzeichen aufteilen? (2076 mal gelesen)
|
Schachinger Ehrenmitglied V.I.P. h.c. Konstrukteur
Beiträge: 2041 Registriert: 08.04.2002 AIS2009, PDSU 2012-2015, Plant 3D 2011-2015, NavisWorks 2010-2015, Win7 64bit SP1, Intel Core i7 870, 16 GB RAM, Quadro 2000D
|
erstellt am: 22. Feb. 2004 21:15 <-- editieren / zitieren --> Unities abgeben:
hallo forum - wieder mal eine sache wo mein bergrenztes lisp-wissen versagt... wenn ich mir mittels "open" und "rline" eine ascii-datei öffne bekomme ich ja wunderbar jede zeile als string raus... mein problem ist das in einer zeile z.b. steht: layer="test 0" "12" colour="1" wie kann ich diesen string am einfachsten zerlegen in einzelne strings die dann "test_0", "12" und "1" enthalten. also immer das " als trennzeichen zu verstehen. leerzeichen als trennung geht leider nicht da manche daten die ich brauche zw. den anführungszeichen auch leerzeichen enthalten. darum die " als trennung. eine zeile wird nie mehr als 10 solcher einträge enthalten. also eine elendlange zeile wird nie zu verarbeiten sein - das sollte nicht das problem sein. ich hoffe mir kann irgendjemand weiterhelfen. besten dank im vorraus! ------------------ mfg Siegfried Schachinger http://www.tbschatz.at [Diese Nachricht wurde von Schachinger am 22. Feb. 2004 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 22. Feb. 2004 21:44 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
Hallo Siegfried, da man so etwas immer wieder brauch, habe ich mir bereits vor einiger Zeit mal eine solche Funktion geschrieben. Aufrufen: (setq Stringliste (f:str-teilen "String" "Trennzeichen"))
Code:
(defun f:str-teilen (sil_str sil_tr / sil_i sil_str1 sil_trli) (setq sil_i 0) (if (= 'STR (type sil_str)) (progn (while (< sil_i (strlen sil_str)) (setq sil_i (1+ sil_i) sil_str1 (substr sil_str sil_i 1) ) (if (= sil_str1 sil_tr) (setq sil_trli (cons sil_i sil_trli)) ) ) (setq sil_trli (reverse sil_trli) sil_z 0) (apply 'append(mapcar '(lambda (P / z) (setq sil_z (1+ sil_z)) (cond ((and(= sil_z (length sil_trli)) (= sil_z 1) ) (list (substr sil_str 1 (1- P)) (substr sil_str (1+ P)) ) ) ((= sil_z 1) (list(substr sil_str 1 (1- P))) ) ((= sil_z (length sil_trli)) (list(substr sil_str (setq z(1+ (nth (- sil_z 2) sil_trli))) (- P z)) (substr sil_str (1+ P))) ) (T (list(substr sil_str (setq z(1+ (nth (- sil_z 2) sil_trli))) (- P z))) ) ) ) sil_trli ) ) ) ) )
Bei Fragen ... Grüße Holger ------------------ Holger Brischke (defun - Lisp over night! AutoLISP-Programmierung für AutoCAD Da weiß man, wann man's hat! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 23. Feb. 2004 01:21 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
|
Schachinger Ehrenmitglied V.I.P. h.c. Konstrukteur
Beiträge: 2041 Registriert: 08.04.2002
|
erstellt am: 23. Feb. 2004 12:46 <-- editieren / zitieren --> Unities abgeben:
|
fuchsi Mitglied Programmierer c#.net Datawarehouse
Beiträge: 1201 Registriert: 14.10.2003 AutoCad Version 2012 deu/enu <P>Windows 7 64bit
|
erstellt am: 23. Feb. 2004 12:50 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
na dann muss auch noch meinen senf dazugeben ;------------------------------------------------------------------------------ ; Fuktion Split ; wandelt einen string in eine liste um ; (split "Anton Berta Cäsar" " ") -> '("Anton" "Berta" "Cäsar") ;------------------------------------------------------------------------------ (defun Split (String Separator / ) (setq String (replace String Separator "\"\"")) (setq String (strcat "(list \"" String "\")")) (eval (read String)) ) ;------------------------------------------------------------------------------ ; Replace Funktion ersetzten eines Suchstrings durch den ReplaceString ; ;------------------------------------------------------------------------------ ; -> String zu durchsuchender String ; -> Searchstring zu suchender/ersetztender string ; -> ReplaceString string mit dem ersetzt wird ;------------------------------------------------------------------------------ (defun Replace (String SearchString ReplaceString / ) (while (/= String (vl-string-subst ReplaceString SearchString String)) (setq String (vl-string-subst ReplaceString SearchString String)) ) String )
------------------ Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 23. Feb. 2004 13:36 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
|
fuchsi Mitglied Programmierer c#.net Datawarehouse
Beiträge: 1201 Registriert: 14.10.2003 AutoCad Version 2012 deu/enu <P>Windows 7 64bit
|
erstellt am: 23. Feb. 2004 14:52 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
|
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 23. Feb. 2004 16:41 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
|
Dabrunz Mitglied
Beiträge: 127 Registriert: 28.05.2003
|
erstellt am: 24. Feb. 2004 09:32 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
Zitat: Original erstellt von mapcar: Mir ist aber gar nicht klar, wo die Backslashs bleiben... Eines ist jedoch sicher: Diese Funktion versagt völlig, wenn es sich um Strings mit Anführungszeichen handelt:(split "a b \"c\" d e" " ") => ("a" "b" "" nil "" "d" "e") ;falsch (str-tok "a b \"c\" d e" " ") => ("a" "b" "\"c\"" "d" "e") ;richtig
Ja, so ist es. Das liegt am read, denn dadurch wird aus "\\" nur noch "\" und somit eine ESC-Sequenz. Ziemlich witzig, wenn im Pfad sowas wie "C:\\treiber" zu finden ist oder gar "s:\\resource" .. Übrigens möchte ich auch noch erwähnen, dass ich die fuchsi-Methode auch mal recht attraktiv fand, weil sie so schön knapp ist. Allerdings verliert sie einiges an Charm, wenn alle "\x" als Sonderfall abgehandelt werden müssen. Das führt zu einer vergl'weise unübersichtlichen Lösung. Allerdings war der Ansatz recht performant - schnell aber falsch - weshalb ich eine Funktion auf Basis von vl-string-search gebastelt habe, die etwas flotter als das obige :str-tok zu Werke geht: Code:
(defun :str-tok (#str #tok / pos tokenOffset wordList) ;** 1.Pos.an d.Pattern <#old> auftaucht (setq pos (vl-string-search #tok #str) ;** verschiebung im String zum Auffinden des nächsten Tokens (1+ TokenLength) tokenOffset (1+(strlen #tok)) ); end SETQ (while pos (setq wordList (cons (:str-first-n #str pos) wordList) #str (substr #str (+ pos tokenOffset)) ;** sucht NÄCHST.Vork.v.<#pattern> in <#str> pos (vl-string-search #tok #str) ); end SETQ ); end WHILE:weitere <#tok> vorkommen (reverse (cons #str wordList)) ); end DEFUN <:str-tok>
Achim [Diese Nachricht wurde von Dabrunz am 24. Feb. 2004 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 24. Feb. 2004 18:16 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
|
Dabrunz Mitglied
Beiträge: 127 Registriert: 28.05.2003
|
erstellt am: 25. Feb. 2004 10:43 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
Moin Axel. Ich kann die Zeitmessung nicht nachvollziehen. Bei mir kommt ungefähr der Faktor 6 heraus: Code:
(defun getTimeSpanSec(expression n / startTime) (setq expression(eval expression)) (setq startTime(getvar"date")) (repeat n (expression)) (* 86400.0(- (getvar"date")startTime)) )
Mit jeweils einem (gc) vorangestellt ergibt sich auf meinem Rechner: (getTimeSpanSec'(lambda()(str-tok-axel "C:/jhgkjabhc/jsgbcs/khbvsavc/kadkd/kahdh/shit.jpg" "/"))100000) => 34.881 (getTimeSpanSec'(lambda()(str-tok-achim "C:/jhgkjabhc/jsgbcs/khbvsavc/kadkd/kahdh/shit.jpg" "/"))100000) => 6.309 Wenn ich (:str-first-n #str pos) durch den direkten Aufruf von (substr #str 1 pos) ersetze, dann ist die Verbesserung nur marginal (~ 5.95). Besonders drastisch werden die Zeit-Differenzen, wenn lange Zeichenketten, wie z.B. der Supportpfad in Token zerlegt werden (jetz nur mit 10000 Wiederholungen): (getTimeSpanSec'(lambda()(str-tok-axel *SupportPath* ";"))10000) => 11.988 (getTimeSpanSec'(lambda()(str-tok-achim *SupportPath* ";"))10000) => 0.511 Versuch's doch nochmal - Achim Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 25. Feb. 2004 13:57 <-- editieren / zitieren --> Unities abgeben: Nur für Schachinger
|