Reguläre Ausdrücke

selberbauer

Captain
Registriert
Juni 2009
Beiträge
3.604
Hi,

ich möchte bei meinem PHP Projekt auf ein nerviges Captcha verzichten und eine gute Validierung einsetzen, dabei soll nach:

1.) Beleidigungen
2.) Buchstabengedrücke (bsp. aaaaaaaaaaaaaaaaaaaaa)

gesucht werden.

Ist dies mit Regex möglich?
 
ersteres nein, zweites ja.

Fuer ersteres muss ein ganzes woerterbuch mit solchen Begriffen vorhanden sein um das abzufangen..
 
Fuer ersteres muss ein ganzes woerterbuch mit solchen Begriffen vorhanden sein um das abzufangen..

Naja ich denke 10 bis 20 Klassiker reichen um die kleinen zu demotivieren ;)

Lassen sich Abwandlungen von den Wörtern auch erfassen, wenn man die Kraftausdrücke nichtmal schreiben kann?
 
Nicht wirklich... Beispiel:

arschloch
4rschloch
ar5chloch
arsch loch
ar sc hl oc h
a r s c h l o c h

Sowas filtert sich nur sehr sehr umständlich.
 
man KÖNNTE ... (jetzt wird's gleich grauenvoll, RegExp-Liebhaber: Augen zuhalten):

Du legst in deinem PHP ein Wörterbuch an, also einfach ein Array mit allen Beleidigungen etc. und dann geht's ab:
Du nimmst jedes Wort und veränderst es erstmal, damit man z.B. leet-speak (und dergleichen) abfangen kann. D.h. du ersetzt in deinem Array alle Vorkommen von "a" oder "A" durch "(a|4)", dann für "s" bzw. "S" ein "(s|5)" etc. pp. das gänze lässt sich per regexp-replace realisieren.
Gegen mögliche Leerzeichen setzt du zwischen alle Zeichen ein " ?" (also leerzeichen + fragezeichen). Das machst du am Besten vor dem Schritt mit den Buchstaben, weil es sonst noch komplizierter wird ;)
Danach hast du dann schonmal alle möglichen Formen von Schreibweisen abgedeckt und danach konkatenierst du alle erzeugten regulären Ausdrückt mit "|" (also ein ODER) zu einem String zusammen. Diesen String benutzt du dann um einen case-insensitive regexp auf den eingegeben Text loszulassen.

Und nun bitte: Schlagt mich nicht. Es ist potthäßlich, inperformant, etc. pp. aber wohl die "einfachste" Lösung ;)
 
selberbauer schrieb:
Hi,

ich möchte bei meinem PHP Projekt auf ein nerviges Captcha verzichten und eine gute Validierung einsetzen, dabei soll nach:

1.) Beleidigungen
2.) Buchstabengedrücke (bsp. aaaaaaaaaaaaaaaaaaaaa)

gesucht werden.

Ist dies mit Regex möglich?

Wo ist die Verbindung zwischen 1.), 2.) und den Captchas?
Captchas sollen sicherstellen, dass deine Seite mit einem Menschen interagiert und nicht mit einem Skript oder Programm.
 
Captchas können Spammern und Trollen den Spaß verderben, weil es einfach zu nervig sein kann. Er will aber auf die Captchas verzichten und trotzdem Gespamme usw. fernhalten.
 
selberbauer schrieb:
Naja ich denke 10 bis 20 Klassiker reichen um die kleinen zu demotivieren ;)

Lassen sich Abwandlungen von den Wörtern auch erfassen, wenn man die Kraftausdrücke nichtmal schreiben kann?

Sagt dir der levensthein-Algorithmus etwas? Dieser ist interessanterweise in PHP nativ implementiert und so Dinge wie arschloch - 4rschloch - ar5chloch bekommst du damit einfach gefiltert.

http://www.php.net/manual/de/function.levenshtein.php

PHP:
$input = 'ar5ch';
$words = array(
    'arsch',
    'idiot',
    'depp',
    'abschaum'
);

$shortest = -1;

foreach ($words as $word) {
    $lev = levenshtein($input, $word);
    if ($lev == 0) {
        $closest  = $word;
        $shortest = 0;
        break;
    }
    
    if ($lev <= $shortest || $shortest < 0) {
        $closest  = $word;
        $shortest = $lev;
    }
}

echo "Eingegebenes Wort: $input\n";
if ($shortest == 0) {
    echo "Exakter Treffer gefunden: $closest\n";
} else {
    echo "Meinten Sie: $closest?\n";
}

Eingegebenes Wort: ar5ch
Meinten Sie: arsch?


Das hilft dir aber nur bei geringen Abwandlungen.
 
Zuletzt bearbeitet:
Aber damit hast du ja keinen Filter geschaffen. Du hast ja nur den Editier-Abstand berechnet! Aus "abcde" wird dann auch "arsch" in 4 Schritten ;)
Zu dem Algorithmus müsste man dann noch 'nen zweiten Algorithmus schreiben, der bestimmt, ab welchem Unterschiedsgrad das Wort durchgeht...

EDIT:
Nehmen wir einfach mal ein paar Beispiele:
"Scheiße" -> "Scheiße" = 0
"Scheisse" -> "Scheiße" = 2
"5ch3i553" -> "Scheiße" = 5
"5 c h 3 i 5 5 3" -> "Scheiße" = 12
Also hätten wir mit 12 noch ein Schimpfwort, aber mit einem Wert von 12 kann ich quasi jedes beliebige Wort in "Scheiße" umformen. Und auch bei einem Wert von 5 blockiert man so alle möglichen Wörter:
"Schule" -> "Scheiße" = 3

Also vollkommen sinnfrei in dieser Form.
 
Zuletzt bearbeitet:
Ich glaube es ist klar, dass das nur den Ansatz aufzeigen soll. Die Distance sollte bei geringem Wörterbuch natürlich gering gewählt sein, bei wachsendem Wörterbuch auch etwas größer.
 
Anhand welchen Kriterien willst du damit filtern?
Code:
<?php

$v = 'arschloch';
$d = array(
'arschloch',
'ARSCHLOCH',
'a r s c h l o c h',
'ar sc hl oc h',
'ars chl och',
'4r5chl0ch',
'4R5CHLOCH',
'arsch',
'testloch',
'hintern',
'attribut',
'zipfelklatscher',
'klatschen',
'amsel',
'argument',
'amortisieren',
'affe',
'affen',
'gehege',
'test',
'Desoxyribonukleinsäure',
'UserAgent',
'foreach',
'OK',
'GNA',
'foo',
);

foreach( $d as $k )
  echo $k.' = '.levenshtein( $k, $v ).'<br>';
Ausgabe:
Code:
arschloch = 0
ARSCHLOCH = 9
a r s c h l o c h = 8
ar sc hl oc h = 4
ars chl och = 2
4r5chl0ch = 3
4R5CHLOCH = 9
arsch = 4
testloch = 4
hintern = 9
attribut = 8
zipfelklatscher = 12
klatschen = 7
amsel = 6
argument = 7
amortisieren = 10
affe = 8
affen = 8
gehege = 8
test = 8
Desoxyribonukleinsäure = 21
UserAgent = 9
foreach = 7
OK = 9
GNA = 9
foo = 8
Zuverlässig filtern kannst du damit nicht wirklich. Ähnliche Wörter werden somit gleich komplett gefiltert, ein Wort in Capslock geschrieben, wird evtl. gar nicht gefiltert. Dann muss zusätzlich jedes einzelne Wort gefiltert werden -> imho zu viel Aufwand des Guten und zu wenig Nutzen.
 
@Yuuri: Natürlich könnte man vorher noch alles ->lowercase machen und dann prüfen :D Aber das Ergebnis wird nicht brauchbarer!
 
Wenn man die Distance in Abhängigkeit der Wortlänge ansteigen lässt, sehe ich für einen Grundfilter kein Problem.

Wenn du ein böses Wort mit 12 Stellen hast und die Distance 3 ist, dann kann man wohl mit großer Sicherheit sagen, dass gefiltert werden muss. Bei einem Wort mit 5 oder 6 Stellen und einer Distance von 1 oder 2 genauso. Natürlich eignet es sich somit für kurze Wörter nicht wirklich, aber die Operation Als Grundfilter ist zig mal billiger als irgendwelche Regex-Ansätze.
 
Nehmen wir: Wichser und Wechsel. Abstand = 2. Sagt NICHTS aus! Ende der Diskussion
Anderes Beispiel? Ficken und Flicken. Abstand = 1. Oh nein.
"Ich hab mir 'nen Flicken auf die Hose genahäht" -> EEEEK -> Du dreckige Sau, hör auf zu fluchen!!!
 
Code:
<?php

$text = 'Die Microsoft Corporation [\'ma?.k?o?.s?ft] ist ein multinationaler Softwarehersteller mit ca. 93.000 Mitarbeitern weltweit und einem Umsatz von 69,94 Milliarden US-Dollar. Der Hauptsitz liegt in Redmond, einem Vorort von Seattle (US-Bundesstaat Washington), und seit 2000 ist Steve Ballmer Chief Executive Officer (CEO). Das Unternehmen ist bekannt für sein Betriebssystem Windows und seine Büro-Software Office.

Das Unternehmen wurde am 4. April 1975 von Bill Gates und Paul Allen gegründet. Die Firma Microsoft steht für Microcomputer-Software, ursprünglich Micro-Soft. Nach anfänglichen Erfolgen mit einem BASIC-Interpreter Ende der 1970er Jahre hat das Unternehmen 1981 das Betriebssystem MS-DOS vorgestellt, dessen Entwicklung im Auftrag von IBM durchgeführt wurde. Der IBM-PC und dessen Nachbauten auf PC-Basis wurden in den 1980er Jahren vornehmlich mit diesem DOS-Betriebssystem ausgestattet. In den 1990er Jahren wurden das grafische Betriebssystem Windows und Microsofts Büro-Software Office Marktführer.

Da PCs allmählich Einzug in das Wohnzimmer nahmen, entwickelte Microsoft die Betriebssystem-Variante Windows XP Media Center Edition (Windows MCE), mit der ein normaler PC mit entsprechender Hardware zum Media Center umfunktioniert werden kann. Windows XP Media Center Edition basiert auf Windows XP, wurde jedoch um spezifische Funktionen (wie Aufnahmefunktion von Filmen, Programmzeitschrift etc.) erweitert.

Des Weiteren vertreibt das Unternehmen seit 2002 das Betriebssystem Microsoft Windows Mobile, das auf mobilen Geräten zum Einsatz kommt. Die Fachpresse moniert derzeit noch die mangelhafte Benutzerfreundlichkeit.[16]

Seit 2007 vertreibt Microsoft die Linux-Distribution Suse Linux Enterprise. Nach Angaben von Heise habe Microsoft mit dem Verkauf von Coupons im Wert von 240 Millionen US-Dollar Platz 3 der Linux-Anbieter erklommen.[17]

Auf den meisten PCs ist ein Betriebssystem von Microsoft installiert. Die einzigen bedeutenden Ausnahmen sind Apple mit dem eigenen Betriebssystem Mac OS (5 % Marktanteil) und diverse Linux-Distributionen (1 % Marktanteil).[18]

Eine komplett neue Linie, aufbauend auf Systemen, die nur noch aus einer oder mehreren Berührungsempfindlichen Anzeige(n) bestehen, und welche in Oberflächen (z. B. von Tischen) integriert werden sollen, befindet sich zurzeit mit Microsoft Surface in Entwicklung und ist in Hotels bereits testweise im Einsatz.[19]';

$words = array(
  'arschloch',
  'penner',
  'wichser',
  'muschi',
  'arschgeige',
  'ficken',
  'wichser'
);
$textc = explode( ' ', $text );
define( 'FILTER_DISTANCE', 5 );

foreach( $textc as $wort )
{
  $dofilter = false;
  foreach( $words as $filterword )
    if( !$dofilter )
      $dofilter = levenshtein( $wort, $filterword ) < FILTER_DISTANCE;
  if( $dofilter ) echo '<span style="color:red;">'.$wort.'</span> ';
  else echo $wort.' ';
}
Ergebnis ist im Anhang. Rote Wörter würden gefiltert werden, zumal es ja noch relativ wenig böse Wörter sind.
 

Anhänge

  • levenshtein.png
    levenshtein.png
    64,3 KB · Aufrufe: 142
Der Grund warum ich auf die Idee kam ist eine Art Überwachungsmodul für eine in .NET geschriebene Collaboration-Software. Hier werden Werte für komplette Kommentare berechnet und in der Administration als Ranking gezeigt. Moderatoren können verdächtige Beiträge anschauen und bei Bedarf handeln, aber sie werden dennoch veröffentlicht. Das habe ich hier nicht bedacht.

@Yuuri: so war's auch nicht gedacht. Wenn man deine Konstante ersetzt durch (strlen($filterword)/2), nur so als Beispiel ohne Erfahrungswert, dann sind es plötzlich nur noch 2 rote Wörter statt der gefühlten Hälfte.
Das ändert aber nichts an der Problematik bei Ficken vs. Flicken, aber zum automatisierten Melden von verdächtigen Beiträgen lässt es sich sicherlich einsetzen.
 
Zuletzt bearbeitet:
Ich denke auch, dass Wortabwandlungen zu ähnlich sind...

Die Frage ist allerdings in der Tat, was man wirkungsvoll gegen Trolls, Flamer und Spamer macht.

IPs nur einmal pro Sechs Stunden zulassen?
Das würde aufjedenfall die Trolls abhalten.

Bots hoffe ich, werden erstmal von verschiedensten Validierungen abgehalten (DNS-Email-Check, Mindestlänge...)
 
1x alle 6 Stunden? Find ich ein bisschen herbe. Wobei du dann die komplette IP blockieren müsstest, denn Cookies löschen kann jeder.
Aber alles hat seine Vor- und Nachteile
 
Zurück
Oben