Regex: & in Links automatisch korrigieren
AllesMeins
- php
0 wahsaga0 Gunnar Bittersmann0 Marc
0 Felix Riesterer0 Siechfred0 Christian Kruse
Hiho,
stehe gerade vor folgendem Problem. Die Nutzer einer Seite sollen die Möglichkeit haben Links auf der Seite einzutragen. Nun soll die Seite aber trotzdem valide bleiben. Und dies schliesst vor allem ein, das ein & in Links durch & ausgedrückt wird. Habt ihr irgend eine Idee wie ich das mit PHP realisieren kann?
Die Gefahr, die mir dabei Probleme macht, sind die "schlauen" Nutzer, nämlich solche die das & bereits durch ein & ersetzt haben. Dies würde bei einem stupiden "ersetzte alle & durch &" dann ja vollkommen entstellt werden. Das gleiche gilt für Sonderzeichen in der Linkbeschreibung. Also brauche ich eher ein "ersetzte alle & durch & solange dieses & nicht von einem *; gefolgt wird, wobei * für eine beliebige Anzahl von Buchstaben steht". Mir fällt aber keine sinnvolle Lösung für ein passendes Suchmuster ein.
Grüsse
Marc
hi,
Also brauche ich eher ein "ersetzte alle & durch & solange dieses & nicht von einem *; gefolgt wird, wobei * für eine beliebige Anzahl von Buchstaben steht".
Aus welchem Grund würdest du das & bei &ImANonExistendEntity; denn nicht ersetzen wollen?
gruß,
wahsaga
Hiho,
Aus welchem Grund würdest du das & bei &ImANonExistendEntity; denn nicht ersetzen wollen?
Weil mein Interesse da mit ner kompletten Liste aller gültigen Möglichkeiten zu arbeiten doch eher gering ist. Da versuche ich nen Ausgleich zwischen "wahrscheinlichkeit das der Fall eintritt" und "Arbeits und Systemaufwand diesen fall abzufangen" zu finden. Ich vermute sowieso nicht, das die Nutzer überhaupt wissen, das man Sonderzeichen so codieren sollte. Daher droht die grösste Gefahr von kopierten Texten und Links, bei denen jemand mit Ahnung (oder ein Script) die Sonderzeichen bereits ersetzt hat. Es ist also recht unwahrscheinlich, das eine nicht existierende Entity auftritt.
Es sei denn dir fällt aus dem Stehgreif ne Lösung ein, wie ich ohne all zu grossen Aufwand nur die existierenden Entitys ersetzten kann...
Marc
AllesMeins,
Die Gefahr, die mir dabei Probleme macht, sind die "schlauen" Nutzer, nämlich solche die das & bereits durch ein & ersetzt haben. Dies würde bei einem stupiden "ersetzte alle & durch &" dann ja vollkommen entstellt werden.
… und durch nachfolgendes "ersetzte alle & durch &" wieder korrigiert.
Elegant find ich das zweifache Suchen und Ersetzen allerdings nicht. Ich würd eine bessere Lösung vorziehen … (wenn es sie gibt)
Live long and prosper,
Gunnar
Hiho,
hmm, dieses zweimalige drübergehen wollte ich eigentlich vermeiden. In dem Fall wäre es dann wahrscheinlich auch sinnvoller und den umgekehrten Weg zu gehen. Also im ersten durchgang alle & oder Ü usw. umwandeln zu lassen und dann wieder zurück. Damit erwische ich dann alle gültigen Entitys. Aber irgendwie hab ich da ne innere Blockade ne solche Lösung anzugehen ;)
Marc
Liebe(r) AllesMeins,
wenn Du genauer beschreiben könntest, wie ein User genau einen Link eintragen kann, dann könnte ich Dir vielleicht helfen.
Für mein Gästebuch habe ich ein Suchmuster entwickelt, welches potentielle Internet-URLs in anklickbare Verweise umwandelt. Dabei werden zwar noch keine Umlaut-Domains berücksichtigt, aber für meine Zwecke klappt das alles ganz gut. Ich gehe allerdings zweimal drüber, da ich Adressen mit und ohne "http://" (die "erkennt" man dann am "www"), als auch URLs wie "http://irgendwas.wo", die ohne "www" sind, umwandeln möchte. Ach ja, ich suche in einem HTML-Quelltext nach diesen potentiellen URLs, daher die HTML-Tags in den Mustern. Hier meine Suchmuster, falls Du sie gebrauchen kannst:
/(?is)([ "(]|"|<br />|^)(?<!url()(?<!href=")(www.(?:(?!"|.<|. )[^ <>'"()])+.[a-zA_Z]+(?:/\w*)?)([ ")]|"|<br />)/
/(?is)([ "(]|"|<br />|^)(?<!url()(?<!href=")(http://(www.)?(?:(?!"|.<|. )[^ <>'"()])+.[a-zA_Z]+(?:/\w*)?)([ ")]|"|<br />)/
Liebe Grüße aus Ellwangen,
Felix Riesterer.
Hiho,
ich denke es ist für die Problemstellung unerheblich, auf welche Art die Daten zum System kommen. Wichtig ist lediglich das mein PHP Script auf mysteriöse Weise (in diesem Fall textfield - hätte aber auch per Rauchzeichen und von nem trainierten Affen abgetippt sein können, das würde auch keinen Unterschied machen) einen Link zugeschustert bekommt und mit dem irgendwas tun soll. In diesem Fall sicherstellen das alle & ordentlich codiert sind. Und wenn mich meine RegEx Künste nicht vollkommen betrügen wird genau dieses Problem in deinem Suchmuster nicht berücksichtigt. Aber trotzdem danke ;)
Grüsse
Marc
Tag Marc.
stehe gerade vor folgendem Problem. Die Nutzer einer Seite sollen die Möglichkeit haben Links auf der Seite einzutragen. Nun soll die Seite aber trotzdem valide bleiben. Und dies schliesst vor allem ein, das ein & in Links durch & ausgedrückt wird. Habt ihr irgend eine Idee wie ich das mit PHP realisieren kann?
Mal 'ne Alternative zum RegExp:
$test = "<a href='somewhere/cgi-bin/foo.pl?foo=bar&bar=foo&bla=blubb>Blök</a>";
echo htmlentities(html_entity_decode($test));
Wenn es dir allerdings ausschließlich um das & geht, wäre sowas denkbar:
$test = "<a href='somewhere/cgi-bin/foo.pl?foo=bar&bar=foo&bla=blubb>Blök</a>";
echo preg_replace('/&(?!amp;)/i', '&', $test);
Vielleicht hilft's.
Siechfred
你好 AllesMeins,
benutze da lieber einen richtigen[tm] Parser. Ein Regex kann nicht alle
Möglichkeiten abdecken. Ich habe das mal in C implementiert:
#define MOD_HTMLCOMMENT_QUOTE_SQ 0x1
#define MOD_HTMLCOMMENT_QUOTE_DQ 0x2
#define MOD_HTMLCOMMENT_QUOTE_AMP 0x4
void mod_htmlcomment_append_plaintext(string_t *str,const u_char *content,int maskwhat) {
u_char buff[8],*ptr,*ptr1 = NULL,*val,*safe;
u_int32_t num;
size_t len;
for(ptr=(u_char *)content;*ptr;++ptr) {
/* ampersand, may be an entity */
if(*ptr == '&') {
if(maskwhat & MOD_HTMLCOMMENT_QUOTE_AMP) {
str_cstr_append(str,"&");
continue;
}
/* {{{ nummeric entity */
if(*(ptr+1) == '#') {
safe = ptr;
if(*(ptr+2) == 'x' || *(ptr+2) == 'X') {
for(ptr1=ptr+3;*ptr1 && isdigit(*ptr1);++ptr1);
if(*ptr1 != ';') {
/* hm, entity is fucked up */
str_cstr_append(str,"&");
ptr = safe;
continue;
}
num = strtol(ptr+3,(char **)&ptr,16);
}
else {
if(*ptr1 != ';') {
/* hm, entity is fucked up */
str_cstr_append(str,"&");
ptr = safe;
continue;
}
num = strtol(ptr+2,(char **)&ptr,10);
}
if(num == 0) {
/* entity is really fucked up */
str_cstr_append(str,"&");
ptr = safe;
continue;
}
if((len = unicode_to_utf8(num,buff,7)) == EINVAL) {
/* again, fucked up */
str_cstr_append(str,"&");
ptr = safe;
continue;
}
str_char_append(str,'&');
ptr = safe;
}
/* }}} */
/* {{{ named entity */
else {
for(safe=ptr++,val=ptr;*ptr && isalnum(*ptr);++ptr);
if(!isalnum(*ptr) && *ptr != ';') {
/* entity fucked up */
str_cstr_append(str,"&");
ptr = safe;
continue;
}
if(ptr-val == 0) {
str_cstr_append(str,"&");
ptr = safe;
continue;
}
val = strndup(val,ptr-val);
num = get_named_entity(val);
free(val);
if((len = unicode_to_utf8(num,buff,7)) == EINVAL) {
/* again, fucked up */
str_cstr_append(str,"&");
ptr = safe;
continue;
}
str_char_append(str,'&');
ptr = safe;
}
/* }}} */
}
else if(*ptr == '"') {
if(maskwhat & MOD_HTMLCOMMENT_QUOTE_DQ) str_cstr_append(str,""");
else str_char_append(str,'"');
}
else if(*ptr == '\'') {
if(maskwhat & MOD_HTMLCOMMENT_QUOTE_SQ) str_cstr_append(str,"'");
else str_char_append(str,'\'');
}
else if(*ptr == '<') str_cstr_append(str,"<");
else if(*ptr == '>') str_cstr_append(str,">");
else str_char_append(str,*ptr);
}
}
Die Funktion macht noch einiges mehr als Entities reparieren, aber trotzdem
solltest du sie sehr leicht nach PHP übersetzen können.
再见,
克里斯蒂安