Text aus Textbox auslesen und letztes Wort in Variable
kevin
- javascript
0 LX0 Felix Riesterer
Hi!
Also ich will eine Textbox auslesen in der ein kleiner Satz steht.
Das letzte Wort des Satzes (dieser Satz hat keinen Punkt "." am Ende) soll dann in einer Variable gespeichert werden.
Wie geht sowas?
Die Textbox kannst Du bspw. anhand ihres Namens selektieren document.getElementsByName('textboxname')[0] oder anhand ihrer ID document.getElementById('textboxid').
Den Inhalt der Textbox entnimmt man der Eigenschaft .value - nun hat man einen String, den man beliebig weiterverwerten kann. "Das letzte Wort" zu haben ist in diesem Fall ein Problem, dem man leicht mit einem regulären Ausdruck zu Leibe rücken kann:
/\b(\w+)\W*$/.exec(document.getElementById('textboxid').value);
var letzesWort = RegExp.$1;
Jetzt ist das letzte Wort (und notfalls noch auch ein Punkt, wofür \W* sorgt) in der Variable letztesWort gespeichert.
Gruß, LX
@@LX:
nuqneH
"Das letzte Wort" zu haben ist in diesem Fall ein Problem, dem man leicht mit einem regulären Ausdruck zu Leibe rücken kann:
Und noch leichter mit Stringfunktionen. In solchen Fällen sollten reguläre Ausdrücke nicht eingesetzt werden.
Qapla'
Hallo Gunnar!
"Das letzte Wort" zu haben ist in diesem Fall ein Problem, dem man leicht mit einem regulären Ausdruck zu Leibe rücken kann:
Und noch leichter mit Stringfunktionen. In solchen Fällen sollten reguläre Ausdrücke nicht eingesetzt werden.
Reguläre Ausdrücke sind ganz hervorragende Lösungen für reguläre Probleme, wie bspw. "das letzte Wort". Erst wenn wir auf unreguläre Probleme stoßen (die zugegebenermaßen oft genug vorkommen), sollten wir auf die String-Funktionen zurückgreifen.
Sicherlich kann man den value mit Split an den Leerzeichen unterteilen und aus dem Ergebnis den letzten Wert nehmen. Das geht aber auch nicht viel leichter oder schneller und benötigt zudem noch mehr Code und mehr Speicher.
Gruß, LX
@@LX:
nuqneH
Und noch leichter mit Stringfunktionen. In solchen Fällen sollten reguläre Ausdrücke nicht eingesetzt werden.
Reguläre Ausdrücke sind ganz hervorragende Lösungen für reguläre Probleme, wie bspw. "das letzte Wort".
In der Theorie.
Sicherlich kann man den value mit Split an den Leerzeichen unterteilen und aus dem Ergebnis den letzten Wert nehmen. Das geht aber auch nicht viel leichter oder schneller und benötigt zudem noch mehr Code und mehr Speicher.
Falsch.
var text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.";
var start = new Date();
for (var i = 0; i < 1E4; i++)
{
var lastWord = text.match(/[^ ]+$/);
}
var done = new Date();
alert(done.getTime() - start.getTime());
Braucht bei mir etwa 5 Sekunden.
1E5 Schleifen (also 10 Mal so viele!) mit
{
var lastWord = text.split(" ").pop();
}
dauern etwa 2.5 Sekunden. Also schon 20 Mal so schnell wie mit regulärem Ausdruck.
Aber auch nicht optimal, denn 1E5 Schleifen) mit
{
var lastWord = text.substr(text.lastIndexOf(" ") + 1);
}
dauern nur 100 Millisekunden! 500 Mal schneller als mit regulärem Ausdruck!
Von „Das geht aber auch nicht viel leichter oder schneller“ kann da nun wirklich keine Rede sein.
Qapla'
Hallo Gunnar,
var start = new Date();
for (var i = 0; i < 1E4; i++)
{
var lastWord = text.match(/[^ ]+$/);
}var done = new Date();
alert(done.getTime() - start.getTime());[/code]
Braucht bei mir etwa 5 Sekunden.
Wie hast Du getestet? Safari, Skript in der Adresszeile eingegeben:
javascript:var text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.";var start = new Date();for (var i = 0; i < 1E4; i++){var lastWord = text.match(/[^ ]+$/);}var done = new Date();alert(done.getTime() - start.getTime());
5 Tests durchgeführt, alle bei ca. 310ms
Selbiges mit 1E5 und split().pop():
5 Tests durchgeführt, alle bei zw. 3405ms und 3465ms
Selbiges mit 1E5 und substr():
5Tests durchgeführt, alle unter 75ms (hier deckt sich das mit Deinen Ergebnissen)
nosports-P.
@@Patrick Andrieu (noreg):
nuqneH
Wie hast Du getestet?
Firefox 3.6.3 unter Windows XP.
Safari […]
Hm, dann ist die JS-Engine von Safari wohl bei regulären Ausdrücken schneller als die des Fuchses.
Oder so intelligent, dass sie sinnlos angewandte reguläre Ausdrücke in Stringfunktionsaufrufe umschreibt. ;-)
Qapla'
Firefox 3.6.3 unter Windows XP.
Stimmt, da (Firefox 3.6.3 unter Vista[1]) sieht es etwas anders aus:
RegEx, 1E4:
um 2650ms
split().pop(), 1E5:
um 1800ms
substr(), 1E5:
um 50ms
Safari […]
Hm, dann ist die JS-Engine von Safari wohl bei regulären Ausdrücken schneller als die des Fuchses.
Oder so intelligent, dass sie sinnlos angewandte reguläre Ausdrücke in Stringfunktionsaufrufe umschreibt. ;-)
Wer weiß, kommt vielleicht vom »QuickTime«-Plugin ;)
[1] Vista auf MedionPC mit 4GB RAM, Intel Quad CPU 2,33GHz, Leistungsindex 5.9
P. (IE 8 teste ich jetzt aber nicht)
Hallo!
Oder so intelligent, dass sie sinnlos angewandte reguläre Ausdrücke in Stringfunktionsaufrufe umschreibt. ;-)
Nein, es werden lediglich bereits kompilierte RegExp-Objekte gecached, so dass das sinnlose neudefinieren nichts ausmacht.
Gruß, LX
@@LX:
nuqneH
Nein, es werden lediglich bereits kompilierte RegExp-Objekte gecached, so dass das sinnlose neudefinieren nichts ausmacht.
Und entziehen sich damit Benchmarktests, die auf vielfacher Ausführung des Codes beruhen.
Qapla'
Und entziehen sich damit Benchmarktests, die auf vielfacher Ausführung des Codes beruhen.
Unterschiedliche Browser verwenden unterschiedliche Methoden, um Benchmarks gezielt zu beschleunigen (bspw. Loop Unrolling, Result Caching). Somit sind Deine Benchmarks auch nur sehr bedingt aussagekräftig.
Was für mich wesentlich schwerer wiegt, ist Deine offensichtliche Abneigung gegen Reguläre Ausdrücke. Ich bin auch nicht der Ansicht, dass man sie überall einsetzen muss, aber gelegentlich sind sie wirklich einfache und geeignete Lösungen, beispielsweise in diesem Fall. Wenn wir die sinnvolle Nutzung von RegExp propagieren, bringen wir vielleicht auch mehr Entwickler dazu, diese zu verstehen.
Was ist bspw., wenn der zu bearbeitende Wert statt einem Leerzeichen ein enthalten würde (ja, mir ist auch klar, dass das in der Praxis nicht passieren wird)? An dieser Stelle ist die Flexibilität von RegExp zusammen mit der wesentlich leichteren Möglichkeit, gezielt Änderungen am Suchpattern zu ermöglichen, für mich mit ein Grund, an dieser Stelle RegExp den Vorzug vor einer String-basierten Lösung zu geben.
Gruß, LX
Hi,
Was für mich wesentlich schwerer wiegt, ist Deine offensichtliche Abneigung gegen Reguläre Ausdrücke.
ich denke Du irrst. Beispiel gefällig:
</archiv/2006/3/t126272/#m814810>
Ich bin auch nicht der Ansicht, dass man sie überall einsetzen muss, aber gelegentlich sind sie wirklich einfache und geeignete Lösungen, beispielsweise in diesem Fall.
Gerade in diesem Beispiel sind RegExp wesentlich unverständlicher und ungeeigneter als die einfachen Stringfunktionen.
Will man Werbung für reguläre Ausdrücke machen, sollte man sich bessere Beispiele suchen - und daran denken, wie reguläre Ausdrücke für Anfänger in regulären Ausdrücken aussehen: kryptisch, unverständlich, das verstehe ich nie ...
Freundliche Grüße
Vinzenz
@@LX:
nuqneH
Was für mich wesentlich schwerer wiegt, ist Deine offensichtliche Abneigung gegen Reguläre Ausdrücke.
Ach was. Ich wollte dir schon raussuchen, wie ich mit einem regulären Ausdruck die Gültigkeit einer Datumsangabe prüfe ;-), aber Vinzenz war schneller.
Reguläre Ausdrücke sind ein mächtiges Werkzeug. Sie lassen sich oft sinnvoll einsetzen. Und sie lassen sich oft sinnvoll vermeiden. (Bei der Prüfung der Gültigkeit einer Datumsangabe bspw.)
Qapla'
Hallo, Gunnar!
Erstens ist es absolut unnötig, die RegExp bei jedem Mal neu zu definieren - schon dadurch wird die Messung unzulässig zugunsten der String-Lösung beeinflußt.
Mit "leichter und schneller" ist zweitens nicht nur die Ausführung, sondern insbesondere auch die Wartung und Entwicklung gemeint - immerhin ist beispielsweise die Anpassung, auf den Punkt am Ende zu verzichten, wesentlich leichter.
Zuguterletzt sind insbesondere bei aktuellen Browsern (Safari und Chrome 4, Opera 10.50) die RegExp-Engines noch einmal deutlich optimiert worden, so dass sich hier ein deutlich anderes Ergebnis zeigen dürfte.
Gruß, LX
@@LX:
nuqneH
Erstens ist es absolut unnötig, die RegExp bei jedem Mal neu zu definieren - schon dadurch wird die Messung unzulässig zugunsten der String-Lösung beeinflußt.
Falsch. Die Schleifen bei Benchmarktests dienen ja dazu, in Bereiche zu kommen, wo man Ausführungszeiten messen kann, um dann auf die Ausführungszeit eines Schleifendurchlaufs zu schließen. Dazu muss natürlich der gesamte Code auch immer wieder vollständig ausgeführt werden.
Mit "leichter und schneller" ist zweitens nicht nur die Ausführung, sondern insbesondere auch die Wartung und Entwicklung gemeint - immerhin ist beispielsweise die Anpassung, auf den Punkt am Ende zu verzichten, wesentlich leichter.
Nur dann, wenn man sich mit http://de.selfhtml.org/javascript/objekte/string.htm@title=Stringmethoden nicht sonderlich auskennt. Ansonsten ist
var lastWord = text.substring(text.lastIndexOf(" ") + 1, text.length - 1);
schnell geschrieben.
Zuguterletzt sind insbesondere bei aktuellen Browsern (Safari und Chrome 4, Opera 10.50) die RegExp-Engines noch einmal deutlich optimiert worden
Firefox 3.6.3 ist auch aktuell. Und vermutlich mehr verbreitet als alle die von dir genannten zusammen.
Qapla'
Lieber Gunnar,
var lastWord = text.substring(text.lastIndexOf(" ") + 1, text.length - 1);
dieser Code versagt, wenn die Verhältnisse nicht bis auf's i-Tüpfelchen genau passen. RegExe sind da wesentlich robuster und für "unsaubere Verhältnisse" besser geeignet.
Liebe Grüße,
Felix Riesterer.
@@Felix Riesterer:
nuqneH
dieser Code versagt, wenn die Verhältnisse nicht bis auf's i-Tüpfelchen genau passen. RegExe sind da wesentlich robuster und für "unsaubere Verhältnisse" besser geeignet.
Ich stelle reguläre Ausdrücke nicht generell in Abrede, sondern merke an, dass man in vielen Fällen mit einfachen Stringoperationen besser dran ist. Hier liegt ein solcher Fall vor.
Qapla'
Lieber kevin,
function ermittleLetztesWort (s) {
if (!s) {
return '';
}
s = s.[ref:self812;javascript/objekte/string.htm#split@title=split](' '); // s ist nun ein Array mit Wörtern
s = s.[ref:self812;javascript/objekte/array.htm#pop@title=pop](); // s ist nun ein String und enthält das letzte Wort (mit Punkt)
s = s.[ref:self812;javascript/objekte/string.htm#replace@title=replace]([ref:self812;javascript/objekte/regexp.htm@title=/\.$/], ''); // letzten Punkt entfernen
return s;
}
Liebe Grüße,
Felix Riesterer.
@@Felix Riesterer:
nuqneH
s = s.http://de.selfhtml.org/javascript/objekte/string.htm#split@title=split(' '); // s ist nun ein Array mit Wörtern
s = s.http://de.selfhtml.org/javascript/objekte/array.htm#pop@title=pop(); // s ist nun ein String und enthält das letzte Wort (mit Punkt)
Das geht noch besser.
s = s.http://de.selfhtml.org/javascript/objekte/string.htm#replace@title=replace(http://de.selfhtml.org/javascript/objekte/regexp.htm@title=/\.$/, ''); // letzten Punkt entfernen
Um das letzte Zeichen aus einem String zu extrahieren, ist nun wirklich kein regulärer Ausdruck nötig. (Lies: kein regulärer Ausdruck sinnvoll.)
Qapla'
Lieber Gunnar,
s = s.http://de.selfhtml.org/javascript/objekte/string.htm#split@title=split(' '); // s ist nun ein Array mit Wörtern
s = s.http://de.selfhtml.org/javascript/objekte/array.htm#pop@title=pop(); // s ist nun ein String und enthält das letzte Wort (mit Punkt)Das geht noch besser.
mir egal. So verstehe ich (lies: der OP) meiner Meinung nach das Vorgehen am besten.
s = s.http://de.selfhtml.org/javascript/objekte/string.htm#replace@title=replace(http://de.selfhtml.org/javascript/objekte/regexp.htm@title=/\.$/, ''); // letzten Punkt entfernen
Um das letzte Zeichen aus einem String zu extrahieren, ist nun wirklich kein regulärer Ausdruck nötig. (Lies: kein regulärer Ausdruck sinnvoll.)
Ich will auch nicht irgendein Zeichen am Ende entfernen, sondern nur den Punkt. Und wenn der nicht da sein sollte, dann verursacht meine Code-Zeile keine unerwünschten Manipulationen am "letzten Wort". Wie willst Du das eleganter und schneller hinbekommen?
Liebe Grüße,
Felix Riesterer.
@@Felix Riesterer:
nuqneH
mir egal. So verstehe ich (lies: der OP) meiner Meinung nach das Vorgehen am besten.
„Teile String an Leerzeichen in Array von Wörtern, schlage nach, was pop() tut, und nehme vom Array das letzte Element“ findest du verständlicher als „nehme vom String den Teil vom letzten Leerzeichen bis zum Ende“??
Ich will auch nicht irgendein Zeichen am Ende entfernen, sondern nur den Punkt.
'!' und '?' nicht? Und was ist mit '.“'?
Und wenn der nicht da sein sollte, dann verursacht meine Code-Zeile keine unerwünschten Manipulationen am "letzten Wort". Wie willst Du das eleganter und schneller hinbekommen?
var l = s.length - 1;
if (s[l] == ".") s = s.substr(0, l);
Bzw.
if (s[l] == "." || s[l] == "!" || s[l] == "?") s = s.substr(0, l);
Qapla'
Hallo,
var l = s.length - 1;
if (s[l] == ".") s = s.substr(0, l);
>
> Bzw.
> `if (s[l] == "." || s[l] == "!" || s[l] == "?") s = s.substr(0, l);`{:.language-javascript}
Darfs etwas kryptischer sein? Dann so:
`var l; (l=s.length) && ".!?".indexOf(s[--l])<0 || (s=s.substr(0,l));`{:.language-javascript}
> > `function ermittleLetztesWort(s) { ... }`{:.language-javascript}
Da würde ich einfach meiner Frau zuhören, die hat es immer... ;)
Gruß, Don P