Zurück   Flashforum > Flash > ActionScript > ActionScript 3

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 16-12-2011, 13:04   #1 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
Escaping für JS-String-Literale

Hi!

Gibt es irgendeine Möglichkeit, Strings so zu escapen, dass man sie in JS-String-Literalen verwenden kann.

Bspw.
Der String enthält einen Zeilenumbruch:

Code:
Hallo
Welt!
Nun möchte ich ihn so verwenden, dass ich einen JavaScript-String-Literal draus baue. Bspw.

Code:
var myString:String = "Hallo\nWelt!";
var myJSStringLiteral:String = "\"" + jsEscape(myString) + "\"";
ExternalInterface.call("alert(" + myJSStringLiteral + ")");
Im realen Fall hab ich natürlich keinen Einfluss auf den Inhalt der Variable myString.

Gibt es so eine Funktion, die das leistet, was die erfundene Funktion jsEscape leistet. In PHP kann man es bspw. mit addcslashes bewerkstelligen:

Code:
$myString = "Hallo\nWelt!";
$myJSStringLiteral = "\"" + addcslashes("\n\r\t\0\"\'\\", $myString) + "\"";
//oder so ähnlich
Ich brauche es aber halt für AS3.
ZerNot ist offline   Mit Zitat antworten
Alt 16-12-2011, 13:15   #2 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.162
Das kannst Du mit einem simplen replace lösen:
ActionScript:
  1. var str:String = "Hallo\nWelt!";
  2. str = str.replace("\n", "\\n");
  3. trace(str);
Ich frag mich jedoch wozu das gut sein soll Sowas wie eval gibt es in AS3 doch eh nicht mehr?!
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!
Martin Kraft ist offline   Mit Zitat antworten
Alt 16-12-2011, 13:23   #3 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
Ja ok. Allerdings müsste man dann halt mehrere verkettete Aufrufe machen oder sich mit einer RegExp herumschlagen (ich mag regular expressions nicht).

Der Grund ist ein Aufruf von JavaScripts window.open mit parametern die aus den flashvars stammen.
ZerNot ist offline   Mit Zitat antworten
Alt 16-12-2011, 14:02   #4 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
Hui - hab gerade nach einiger Fehlersuche rausgefunden, das replace ja nur das erste Vorkommen ersetzt. d.h. Ich brauch zusätzlich zur Hintereinanderausführung mit verschiedenen Werten (\n, \t, \r,...) auch für jeden noch eine Schleife.

RegExp geht ja auch nicht, bin ich draufgekommen, weil da 1. das selbe Problem ist 2. zur Vermeidung der Verkettung ist es auch nicht geeignet, weil ich ja in der Ersetzung keine Fallunterscheidung in der RegExp einbauen kann.

Gibt es da nicht doch etwas Kompakteres?
ZerNot ist offline   Mit Zitat antworten
Alt 16-12-2011, 16:41   #5 (permalink)
in the boondocks
 
Benutzerbild von shin10
 
Registriert seit: Feb 2006
Ort: Augsburg
Beiträge: 3.495
Hi,

also zum einen RegExp rocken! ... und kannst du mit replace nicht nur ein, sondern alle Treffer ersetzen. Dazu musst du nur das flag g setzen.

Aber zum Problem: Verwende doch einfach encodeURIComponent()/decodeURIComponent(). Das gibt es in AS wie JS.

mfg

sx
__________________

flintfabrik.de
shin10 ist offline   Mit Zitat antworten
Alt 19-12-2011, 17:08   #6 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
Nein RegExps sucken
Aber mal Spaß beiseite.

(Nein doch noch nicht Spaß beiseite - ich muss kurz erklären, warum ich regexps nicht mag. Aber bitte Vorsicht - das ist kein Feldzug gegen RegExps, sondern ich möchte nur anderen meine Sicht der Dinge schildern. Es ist ein Angebot, die Dinge so zu sehen und jeder kann für sich entscheiden, ob er dieser Sichtweise was abgewinnen kann, oder nicht:
Ich finde, sie sind relativ schlecht lesbar bzw. relativ schlecht intuitiv erfassbar, wenn man sie nicht kennt. Guter Code - egal ob Markup, Konfiguration oder Programmierung oder etwas anderes wie RegExps - sollte lesbar sein, selbst für Leser, die die Sprache nicht gut kennen. RegExps schnell zu erfassen, ist, glaub ich, schon keine ganz triviale Aufgabe mehr,
wenn sie aber dann auch noch neu für einen sind, kann man auch nicht mal ungefähr nachvollziehen, was gemeint ist (keine Sorge - ich hab schon RegExps gemacht - ich meinte das nur prinzipiell ). Bei anderen Sprachen ist das schon möglich: Bspw. Man kann noch nie was von HTML gehört haben, trotzdem kann man sich im Markup zurecht finden und ungefähr nachvollziehen, was gemeint ist. Man braucht JSON nicht zu kennen und kann sich trotzdem ungefähr vorstellen, was ein JSON Code bedeutet. Die Regeln einer EBNF kann man in einer Minute verstehen. Es gibt zahlreiche weitere Beispiele. Riesen wie C++ kann man natürlich nicht sofort behirnen, aber das ist ja auch wesentlich umfangreicher als RegExps.
Ok, nachdem ich dieses Angebot gemacht habe, freue ich mich natürlich, wenn es jemand ähnlich sieht, aber - da es ja ein Angebot ist - trachte ich nicht speziell danach, jemanden zu überzeugen. Es ist eher eine Darstellung meiner Sichtweise die in vollster Wertschätzung der Anhängerschaft von RegExps vorgetragen wird.)

Aber zur Sache

Diese 'g'-Sache gibz nur bei RegExps, oder? Wie dem auch sei, mit RegExps kann man auch die mehrfache Ausführung (einmal für jedes zu maskierende Zeichen) nicht vermeiden.

encodeURIComponent ist (wie der Name sagt) für URIs, nicht für JS-String-Literale. Die Funktion hat also einen anderen Anwendungszweck und ist für diese Anforderungen nicht geeignet.

Ich hatte schon überlegt es händisch zu machen, hab aber aus Faulheit dann eine Variante mit split und join gemacht. Die ist sicherlich nicht ganz effizient, jedoch sollte die Laufzeitkomplexität eher der linearen Kategorie angehören, weshalb ich mich für diese Variante nicht selbst geisseln werden. (Die händische Variante könnte nämlich sogar quadratisch werden - je nachdem, wie die Stringkonkatenation intern funktioniert. Da habe ich aber leider nix drüber gefunden).
ZerNot ist offline   Mit Zitat antworten
Alt 19-12-2011, 18:44   #7 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.162
Keine Frage, RegExp sind nicht einfach zu lesen. Sie erreichen eben einen höheren Abstaktionsgrad als übliche Programmiersprachen, sind aber genau aus diesem Grund aber auch so mächtig und präzise.

Man kann dass durchaus mit mathematischen Formeln vergleichen. Die kommen einem in der Grundschule auch widernatürlich und unleserlich vor. Trotzdem wird sie jeder, der damit umgehen kann, einer textlichen Beschreibung desselben Problems vorziehen!

Reguäre Ausdrücke können sich trotzdem (oder gerade deshalb) positiv auf die Lesbarkeit des GesamtCodes auswirken. Ich jedenfalls finde es deutlich übersichtlicher, mit einer RegExp zu arbeiten, der eine Mail-Adresse validiert, als ein Konstrukt mit mehren Variablendeklarationen und Schleifen in meinen Code integrieren zu müssen.

Lange Rede ... versuch's mal damit:
Code:
function replFunc() {
    var i = String("\n\r\t\v\f").indexOf(arguments[0]);
    return (i<0)? arguments[0] : "\\" + String("nrtvf").charAt(i);
}

var str = "Hallo\n\r\t\f\vWelt \n!"
alert("»" + str + "« = »" + str.replace(/(\s)/g, replFunc) + "«");
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (19-12-2011 um 23:03 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Alt 19-12-2011, 22:48   #8 (permalink)
in the boondocks
 
Benutzerbild von shin10
 
Registriert seit: Feb 2006
Ort: Augsburg
Beiträge: 3.495
Zitat:
Zitat von ZerNot Beitrag anzeigen
encodeURIComponent ist (wie der Name sagt) für URIs, nicht für JS-String-Literale. Die Funktion hat also einen anderen Anwendungszweck und ist für diese Anforderungen nicht geeignet.
Inwiefern soll das ein Problem sein? Sicher ist der String dadurch länger, aber da alles nur lokal ausgeführt wird seh ich das recht schmerzfrei. Du willst doch nur die Sonderzeichen escapen um ... wozu eigentlich? Ist das bei ExternalInterface wirklich notwendig? Hab es über ein Jahr nicht mehr gebraucht.

Und Martin, danke für das schöne Bsp. - und sie rocken doch!
__________________

flintfabrik.de
shin10 ist offline   Mit Zitat antworten
Alt 20-12-2011, 06:38   #9 (permalink)
Neuer User
 
Registriert seit: Nov 2005
Beiträge: 548
Zitat:
Zitat von ZerNot Beitrag anzeigen
[...]ich muss kurz erklären, warum ich regexps nicht mag[...]
Sehe ich (leider) genauso, einfach unleserlich, auch wenn ichs natürlich gerne besser können würde. Fremder oder alter Code wird da für mich zur Qual. Aber wer sich da reindenken kann sollte das tun, das Potenzial dahinter ist keine Frage! Ich hatte mich da mal bei einem BB-Forum teilweise durch den BBCode-Interpreter durchgerungen und auch eigene Codes implementiert - ist schon genial :-)

Ohne dringende Notwendigkeit in einem entsprechenden Projekt wende ich eher split() und join() an - wie es sich da mit Geschwindigkeit und Speicher gegenüber replace verhält weiß ich nicht, aber bisher waren meine Textmengen und Laufzeitverhalten eher unkritisch.

Also für die RegExp-Faulen:
ActionScript:
  1. myString=myString.split("a").join("b"); //ersetzt alle a durch b
  2.  

Geändert von joeydee (20-12-2011 um 06:43 Uhr)
joeydee ist offline   Mit Zitat antworten
Alt 20-12-2011, 09:35   #10 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
@joeydee: genauso hab ich es auch gemacht. :-)

Zitat:
Zitat von Martin Kraft Beitrag anzeigen
Ich jedenfalls finde es deutlich übersichtlicher, mit einer RegExp zu arbeiten, der eine Mail-Adresse validiert, als ein Konstrukt mit mehren Variablendeklarationen und Schleifen in meinen Code integrieren zu müssen.
Das Argument kann ich nachvollziehen.

Zitat:
Zitat von Martin Kraft Beitrag anzeigen
Lange Rede ... versuch's mal damit:
Geniale Idee - gefällt mir!

Zitat:
Zitat von shin10 Beitrag anzeigen
Inwiefern soll das ein Problem sein?
Naja, das Problem ist, dass in einem JS-String-Literal bspw. ein Linefeed so wie in C maskiert werden muss, nämlich so: \n
encodeURIComponent maskiert ihn aber für URIs, und dort werden Linefeeds so maskiert: %0A
ZerNot ist offline   Mit Zitat antworten
Alt 20-12-2011, 10:44   #11 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
@Martin Kraft:
Hi - allerdings muss man die Lösung noch erweitern bzgl. Anführungszeichen und Backslashes. Und da hat dann die Sache mit \s nicht funktioniert.

Hier die modifizierte Variante:

Code:
function jsEscape(string:String):String
{
	function replace():String
	{
		var i:int = String("\n\r\t\v\f\"\'\\").indexOf(arguments[0]);
		return (i < 0) ? arguments[0] : "\\" + String("nrtvf\"\'\\").charAt(i);
	}
	return string.replace(/[\n\r\t\v\f"'\\]/g, replace);
}
Ich kann eh davon ausgehen, dass replace nicht rekursiv ersetzt, oder? Weil sonst könnte es nämlich mit den Backslashes ein Problem geben.

Andere Frage: RegExps können ja mehrdeutig sein. Wie wird das dann bei der Ersetzung gehandhabt. Bspw.
die RegExp wäre /aa|ab/
der Quellstring wäre "aab"
ZerNot ist offline   Mit Zitat antworten
Alt 20-12-2011, 11:17   #12 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.162
Zitat:
Zitat von ZerNot Beitrag anzeigen
Andere Frage: RegExps können ja mehrdeutig sein.
Nein, RegExp sind wie alle Programmiersprachen deterministisch. D.h. sie führen bei jeder Ausführung zum selben eindeutigen Ergebnis.

Dabei werden...
  1. ... die Strings von vorne nach hinten verabeitet, ...
  2. ... Quantoren gierig angewandt (d.h. es wird immer die größtmögliche Treffermenge gewählt) ...
  3. ... und einmal übereinstimmende Zeichen nicht wieder freigegeben (Dieser Punkt ist essentiell um Endlosschleifen auszuschließen!).
Dieses Verhalten lässt sich natürlich auch varieren und steuern. Mehr dazu findest Du z.B. über Wikipedia.

Zitat:
Zitat von ZerNot Beitrag anzeigen
Wie wird das dann bei der Ersetzung gehandhabt. Bspw.
die RegExp wäre /aa|ab/
der Quellstring wäre "aab"
Das lässt sich ja relativ einfach ausprobieren:
PHP-Code:
alert( ("aab").replace(/aa|ab/g"ba") ); // -> bab 
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (20-12-2011 um 12:26 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Alt 20-12-2011, 12:23   #13 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
Zitat:
Zitat von Martin Kraft Beitrag anzeigen
  1. ... die Strings von vorne nach hinten verabeitet, ...
  2. ... Quantoren gierig angewandt (d.h. es wird immer die größtmögliche Treffermenge gewählt) ...
  3. ... und einmal übereinstimmende Zeichen nicht wieder freigegeben (Diese Punkt ist essentiell um Endlosschleifen auszuschließen!).
Genau das wollt ich wissen. Danke.
ZerNot ist offline   Mit Zitat antworten
Alt 20-12-2011, 15:24   #14 (permalink)
in the boondocks
 
Benutzerbild von shin10
 
Registriert seit: Feb 2006
Ort: Augsburg
Beiträge: 3.495
Zitat:
Zitat von ZerNot Beitrag anzeigen
Naja, das Problem ist, dass in einem JS-String-Literal bspw. ein Linefeed so wie in C maskiert werden muss, nämlich so: \n
encodeURIComponent maskiert ihn aber für URIs, und dort werden Linefeeds so maskiert: %0A
Schon klar, drum hab ich ja auch gleich von decodeURIComponent gesprochen um das am Ziel gleich wieder rückgängig zu machen. Aber das Martin dir RegExp schmackhaft machen konnte freut mich noch mehr. Die sind auf jeden Fall einen Blick Wert und nach ein paar Stunden experimentieren ein Werkzeug, auf welches man später kaum mehr verzichten möchte. Ich wünsch dir in Zukunft viel Spaß damit.
__________________

flintfabrik.de
shin10 ist offline   Mit Zitat antworten
Alt 20-12-2011, 16:24   #15 (permalink)
Neuer User
 
Registriert seit: Aug 2011
Beiträge: 16
@shin10

Ok, jetzt hab ich's.
Du meintest etwas in der Art:

Code:
//AS3
ExternalInterface.call("alert(decodeURIComponent(\"" + encodeURIComponent(myString) + "\"))");
Ja stimmt, das müsste gehen. Warum hab ich nicht gecheckt, was du meinst?

Wobei in diesem Fall würde ich escape/unescape nehmen. Die gibz auch in beiden Sprachen und die escapen auch das einfache Hochkomma. In dem obigen Beispiel wäre das einfache Hochkomma zwar prinzipiell egal, weil der Text eh in doppelten eingeschlossen ist und meines Wissens das in AS3 und JS dann nicht escaped werden muss (bitte richtig stellen, falls ich hier einem Irrtum erliege), aber auf das müsste man dann immer achten.

Die Variante gefällt mir sogar am besten.

Ergänzung: An Martins Variante Variante gefiel mir vor allem der Kniff mit der Funktion als Replacement-Parameter (Ich denke immer viel zu objektorientiert und komme dann auf funktionale Lösungen nicht direkt drauf). RegExps werde ich glaube ich weiterhin eher vermeiden ;-)

Geändert von ZerNot (20-12-2011 um 16:28 Uhr)
ZerNot ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Zielfenster durch String bestimmen; navigateToURL(request, STRING); sejau ActionScript 3 13 23-07-2009 09:19
[Flash CS3] %3%% - Escaping bei externen Parametern Firemice Flash Einsteiger 2 06-04-2009 19:02
CSS Style: Style Literale autom. in Nummern konvertieren Warappa Flex programmieren 5 21-11-2008 09:24
loadVar, String OBJ und String splitten /n ... gleich drei Wünsche auf einmal! dragon ActionScript 1 9 21-11-2004 01:18
Escaping und Umbruch -Panda- Flash mit XML und Webservices 1 23-08-2004 23:37


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele