Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]7875[/thread]

Doppelbuchstaben umklammern (war: Help) (Seite 2)



<< |< 1 2 3 >| >> 23 Einträge, 3 Seiten
Dubu
 2006-04-11 00:16
#64678 #64678
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Ich denke hier hat keiner etwas gegen die Verwendung von \w - wenn das gemeint ist. Aber \w passt halt auf mehr als nur Buchstaben: Es passt auf Buchstaben, Ziffern und Unterstrich.

Mein Gegenvorschlag für "nur Buchstaben" wäre [:alpha:].


Edit: Sch.. Shortcuts. Ich muss das im Konq mal abstellen...\n\n

<!--EDIT|Dubu|1144700266-->
sid burn
 2006-04-11 00:55
#64679 #64679
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=Dubu,10.April.2006, 22:16]Aber \w passt halt auf mehr als nur Buchstaben: Es passt auf Buchstaben, Ziffern und Unterstrich.

Mein Gegenvorschlag für "nur Buchstaben" wäre [:alpha:].[/quote]
Okay das stimmt.
Aber auf Buchstaben sollte es ja schon matchen, ist ja Sinn der Sache.

Allerdings matcht \w bei mir auf keine Ziffern..."0", "1", "2", ... dafür gibt es ja "\d". Das mit dem Unterstrich ist wohl war, dass ist aber das einzige, und ließe sich auch ohne die Posix Zeichenklasse lösen.

Und habe gerade zum ersten mal die Posix Zeichenklasse "live" ausprobiert. Habe da vorher immer nur drüber gelesen, da ich nie eine verwendung dafür sah. Das man es nur innerhalb einer Zeichenklasse benutzten kann ist ja mal ...\n\n

<!--EDIT|sid burn|1144703746-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
Dubu
 2006-04-11 01:23
#64680 #64680
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=sid burn,10.04.2006, 22:55]Aber auf Buchstaben sollte es ja schon matchen, ist ja Sinn der Sache.
[/quote]
Ja, so habe ich das auch verstanden.

Quote
Allerdings matcht \w bei mir auf keine Ziffern..."0123", dafür gibt es ja "\d".

Dann probier's nochmal. ;)
Oder lies perlre.

Quote
Das mit dem Unterstrich ist wohl war, ließe sich aber auch ohne die Posix Zeichenklasse lösen.

Und wie?

Quote
Und habe gerade zum ersten mal die Posix Zeichenklasse "live" ausprobiert. habe da vorher immer nur drüber gelesen, da ich nie eine verwendung dafür sah. Das man es nur innerhlab einer Zeichenklasse benutzten kann ist ja mal ...

Tja, ist wohl POSIX-Standard.
sid burn
 2006-04-11 02:06
#64681 #64681
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=Dubu,10.April.2006, 23:23]Dann probier's nochmal. ;)
Oder lies perlre.

Quote
Das mit dem Unterstrich ist wohl war, ließe sich aber auch ohne die Posix Zeichenklasse lösen.

Und wie?

Quote
Und habe gerade zum ersten mal die Posix Zeichenklasse "live" ausprobiert. habe da vorher immer nur drüber gelesen, da ich nie eine verwendung dafür sah. Das man es nur innerhlab einer Zeichenklasse benutzten kann ist ja mal ...

Tja, ist wohl POSIX-Standard.[/quote]
Also bei mir hat "\w" noch nie auf "1" gematcht. Kann ich so oft wiederholen wie ich möchte. Und ein Blick in perlre bestätigt das gleiche.

Quote
\w Match a "word" character (alphanumeric plus "_")

heißt für mich so viel wie matcht auf alle alphanumerischen zeichen + den unterstrich. Was da aber nicht bei steht. Es matcht natürlich auch auf alle Unicode zeichen die in der Locale sind, und nicht nur auf [a-zA-Z_] was manche meinen.

Wenn du es also so siehst ist "\w" identisch zur folgenden Zeichenklasse: "[[:alpha:]_]". Naja fast. Unicode Zeichen können sich nämlich aus mehrere einzelnen zeichen zusammen setzen, und ein neues zeichen Bilden. Das erkennt "\w" nicht. Aber "\X" erkennt das als ein zeichen. Ich denke mal "[:alpha:]" erkennt solche zusammengesetzte Zeichen auch. Allerdings finde ich in perlre dazu keine Informationen, dass es das auch tut. Ich kann aber Morgen nochmal im Reguläre Ausdrücke Buch nachlesen ob es das nun tut, oder nicht. Sollte aber an der Tatsache das es immer noch keine Ziffern erkennt nichts dran ändern?


Du verwechselst jetzt aber nicht "\w" mit "\W", oder? Das zweite matcht schon auf Ziffern...


Ohne Posix Zeichenklasse könnte man das folgendermaßen lösen.

Code: (dl )
s/(?!_)(\w)\1/($1$1)/ig


Ist ein Negatives Lookahead Konstrukt das auf eine Position matcht, wenn danach kein "_" kommt. Also kurz gesagt jedes "_" wird überpsungen. Danach wird "\w" angewendet. Da ja jedes "_" übersprungen wird, kann ja nur noch ein alphanumerisches zeichen in der Variablen $1 sein.

Natürlich auch alle Möglichen Unicode alphanumerischen Zeichen die zum aktuellen locale gehören. Was aber denke ich gewünscht sein sollte.

Quote
Tja, ist wohl POSIX-Standard.

Nichts gegen den Posix Standard. Aber was Reguläre Ausdrücke angeht ist der Posix Standard Meiner Meinung nach Müll.\n\n

<!--EDIT|sid burn|1144708959-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
Dubu
 2006-04-11 04:08
#64682 #64682
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=sid burn,11.04.2006, 00:06]Also bei mir hat "\w" noch nie auf "1" gematcht. Kann ich so oft wiederholen wie ich möchte.
[/quote]
Dann ist dein Perl kaputt.
Beispiel gefällig?
Code: (dl )
1
2
$ perl -Mstrict -Mwarnings -le 'my $str="a1+b2+c3"; $str =~ s/\w/./g; print $str'
..+..+..


Quote
Und ein Blick in perlre bestätigt das gleiche.

Quote
\w  Match a "word" character (alphanumeric plus "_")

heißt für mich so viel wie matcht auf alle alphanumerischen zeichen + den unterstrich.

Und was heißt "alphanumerisch"? Richtig: "alphabetisch + numerisch".

Quote
Was da aber nicht bei steht. Es matcht natürlich auch auf alle Unicode zeichen die in der Locale sind, und nicht nur auf [a-zA-Z_] was manche meinen.

Naja, es steht implizit drin. Es passt auf alle alphanumerischen Zeichen der Locale + Unterstrich. Wenn deine Locale auf Unicode basiert, dann passen auf \w eben alle Unicode-Zeichen, die (in deiner Locale?) alphanumerisch sind. Plus den Unterstrich.

Quote
Wenn du es also so siehst ist "\w" identisch zur folgenden Zeichenklasse: "[[:alpha:]_]". Naja fast.

Eher "[[:alnum:]_]".

Quote
Unicode Zeichen können sich nämlich aus mehrere einzelnen zeichen zusammen setzen, und ein neues zeichen Bilden. Das erkennt "\w" nicht.

Hm. Wie meinst du das? Sowohl UTF-8 als auch UTF-16 bestehen natürlich aus Mehrbytesequenzen, das ist klar. Aber jede Sequenz sollte doch eindeutig sein, oder?

Quote
Aber "\X" erkennt das als ein zeichen. Ich denke mal "[:alpha:]" erkennt solche zusammengesetzte Zeichen auch.

Ah, jetzt weiß ich, was du meinst. Man kann Zeichen mit mehreren "Akzenten" kombinieren, z.B. im Arabischen. Tja, da habe ich auch keine Ahnung, wie das in Regexen aussieht.
Ich erwarte aber, dass \w und [:alnum:] bis auf den Unterschied mit dem Unterstrich gleich funktionieren.

Quote
Allerdings finde ich in perlre dazu keine Informationen, dass es das auch tut. Ich kann aber Morgen nochmal im Reguläre Ausdrücke Buch nachlesen ob es das nun tut, oder nicht. Sollte aber an der Tatsache das es immer noch keine Ziffern erkennt nichts dran ändern?

Tut's ja doch. ;)

Quote
Du verwechselst jetzt aber nicht "\w" mit "\W", oder? Das zweite matcht schon auf Ziffern...

Nö, tut's nicht. ;)
Crian
 2006-04-11 11:49
#64683 #64683
User since
2003-08-04
5873 Artikel
ModeratorIn
[Homepage]
user image
Ich würde ja mal kurz auf der Konsole testen, bevor ich so schlicht falsche Dinge verbreite =)

Code: (dl )
1
2
3
4
5
6
C:\>perl
my $text = 'a1b2c3d4';
$text =~ s~\w~#~g;
print $text;
^Z
########


Ich mag \w nicht so gern, weil man sich dann nicht darauf verlassen kann, dass das Programm überall das gleiche macht. Ich hatte jedenfalls schonmal unangenehme Überraschungen bei der Verwendung von \w.\n\n

<!--EDIT|Crian|1144741907-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
sid burn
 2006-04-11 12:16
#64684 #64684
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Quote
Dann ist dein Perl kaputt.
Beispiel gefällig?
Code: (dl )
1
2
$ perl -Mstrict -Mwarnings -le 'my $str="a1+b2+c3"; $str =~ s/\w/./g; print $str'
..+..+..


Man man man, du hast jetzt mein regex leben auf dem Kopf gestellt. ;) Jetzt befasse ich mich schon so intensiv mit Regexe, und mir ist das bisher nicht aufgefallen.

Anhand dieser Tatsache ist dann "\w" wirklich ungeeignet, und eine Posix zeichenklasse ist dafür dann deutlich besser geeignet.

Quote
Quote
Unicode Zeichen können sich nämlich aus mehrere einzelnen zeichen zusammen setzen, und ein neues zeichen Bilden. Das erkennt "\w" nicht.

Hm. Wie meinst du das? Sowohl UTF-8 als auch UTF-16 bestehen natürlich aus Mehrbytesequenzen, das ist klar. Aber jede Sequenz sollte doch eindeutig sein, oder?

Ne, leider nicht.

Unicode und UTF-8 / UTF-16 sind zwei unterschiedliche Dinge.

Unicode selber ist eine Zuordnung zwischen Zeichen und Zahlen. Allerdings kann, und es ist auch so. Das andere Unicode Zeichen wiederum aus mehrere Unicode Zeichen zusammengesetzt sind.

Diese Unicode zeichen müssen letztendlich auf dem Bildschirm angezeigt werden. Dafür gibt es dann UTF-8 und UTF-16. Allerdings bedeutet es nicht das ein und das selbe Zeichen die gleichen bytesequenz in den verschieden Codierungen wie UTF-8 / UTF-16 / UCS-2 / UCS-4 besitzt. Ein und das selbe Zeichen hat unterschiedliche Codierungen in UTF-8, UTF-16... aber trotzdem eine fest zugewiesene Unicode Codierung.


Nehmen wir als Beispiel folgendes zeichen "á", (eigentlich wollte ich den Strich von links oben nach unten aber ist für das beispiel irrelevant). Das ganze setzt sich aus 2 Unicode Zeichen zusammen.

U+0061 und U+0300. In UTF-8 existiert dafür aber nur eine Bytecodierung. Das Problem ist jetzt wenn du dieses zeichen direkt in einer Regex schreiben würdest, z.b in einer zeichenklasse, dann wäre es das selbe als wenn du "[a`]" schreiben würdest. Du erkennst auf einmal zwei zeichen, nämlich ein normales a, und einmal das hochkomma. Aber nicht das zusammengesetzt Zeichen á.

Das liegt darin das die UTF-8 Codierung das ganze in die beiden Unicode Zeichen umwandelt. Also "U+0300+U+0061", und jetzt jedes zeichen einzeln erkennt, und nciht beide zeichen zusammen zu einem zeichen.

Das gleiche Problem existiert bei dem "." oder "\w".

"^.$" würde z.B. nicht auf "á" passen. Da es in Unicode zwei Zeichen sind, und der Punkt nur eins erkennt. Der Punkt erkennt hier nicht das beide Unicode zeichen eigentlich ein zeichen darstellen.

"^..$" wäre aber in der Lage auf "á" zu matchen.

Oder man benutzt eben "\X", dass solche zusammengesetzte Zeichen (combining characters) erkennt. "^\X$" würde also auf "á" matchen. Und es können noch komplexere Zeichen aus mehreren Unicode Zeichen erkannt werden. "\X" erkennt das hier als ein zeichen.

Das ist nicht mit UTF-8 zu verwechseln. Den für jedes Zeichen gibt es zwar nur eine Bytefolge, es kann aber trotzdem aus mehrere Unicode Zeichen bestehen. und perl arbeitet auf unicode ebene.

Noch Lustiger ist es wenn du so ein zeichen schreibst und ein Quantor benutzt. "á+" Das erkennt nicht mehrere "á", sondern ein "a" gefolgt von mindestens ein und mehrere "`".


Quelle:
Buch Reguläre Ausdrücke. Deutsche Ausgabe.
2. Auflage
S. 109ff.\n\n

<!--EDIT|sid burn|1144744057-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
Strat
 2006-04-11 14:31
#64685 #64685
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
was spricht gegen:
Code: (dl )
$string =~ s/(\w)\1/($1$1)/g; # buchstaben klammern

oder:
Code: (dl )
1
2
3
4
5
6
7
$string =~ s/
\b # wortgrenze
([A-Za-z]*?) # ev. Buchstaben bis zum ersten vorkommen
([A-Za-z]) \2 # des doppelbuchstabens
([A-Za-z]*?) # noch ev. weitere buchstaben, egal, ob doppelt oder nicht
\B # bis zur naechsten wortgrenze
/($1$2$2$3)/gx;

wenn's nicht [A-Za-z] sein soll, dann das entsprechende ersetzen, oder POSIX-Characterklassen verwenden...
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
renee
 2006-04-11 14:43
#64686 #64686
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Dein zweiter Code haut nicht hin:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/perl

use strict;
use warnings;

my $string = "hallsso";

$string =~ s/
\b # wortgrenze
([A-Za-z]*?) # ev. Buchstaben bis zum ersten vorkommen
([A-Za-z]) \2 # des doppelbuchstabens
([A-Za-z]*?) # noch ev. weitere buchstaben, egal, ob doppelt oder nicht
\B # bis zur naechsten wortgrenze
/($1$2$2$3)/gx;

print $string,"\n";


Ausgabe:
Code: (dl )
1
2
~/entwicklung 394> perl doppel.pl 
(hall)sso


Es klammert falsch und wenn mehrere Doppelbuchstaben hintereinander auftauchen werden die nach dem ersten Doppelbuchstaben nicht markiert!
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
ptk
 2006-04-11 22:44
#64687 #64687
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=sid burn,11.04.2006, 10:16]Nehmen wir als Beispiel folgendes zeichen "á", (eigentlich wollte ich den Strich von links oben nach unten aber ist für das beispiel irrelevant). Das ganze setzt sich aus 2 Unicode Zeichen zusammen.[/quote]
Das stimmt so nicht. Man *kann* dieses Zeichen aus zwei Unicode-Zeichen ("a" und "combining acute") kombinieren, aber üblich ist das nicht. Normalerweise nimmt man da gleich \x{00e1} (LATIN SMALL LETTER A WITH ACUTE) und muss sich nicht mit \X und Normalisation (dazu gibt es auch ein Perl-Modul: Unicode::Normalize) herumschlagen.
<< |< 1 2 3 >| >> 23 Einträge, 3 Seiten



View all threads created 2006-04-10 16:52.