29 votes

Les symboles d'expression régulière preg_quote ne sont pas détectés

J'ai un dictionnaire des gros mots dans la base de données, et le suivant fonctionne très bien

preg_match_all("/\b".$f."(?:ing|er|es|s)?\b/si",$t,$m,PREG_SET_ORDER);

$t est la saisie du texte et simplement, $f = preg_quote("punk"); "punk" est à partir de la base de données du dictionnaire, de sorte à ce point dans la boucle de l'expression comme suit

preg_match_all("/\bpunk(?:ing|er|es|s)?\b/si",$t,$m,PREG_SET_ORDER);

preg_quote remplace les symboles, par exemple. # avec \\# de sorte que l'expression est échappé, mais lorsque le dictionnaire est en train de vérifier par exemple. "F@CK" ou "A$$" ces symboles ne sont pas détectés dans la chaîne d'entrée avec l'expression ci-dessus, j'ai à la fois a$$ et f@ck dans le dictionnaire, mais ils ne fonctionnent pas. Si je supprime preg_quote() sur le mot, l'expression régulière n'est pas valide tant que ces symboles ne sont pas échappé.

Toutes les suggestions sur comment je peux détecter "a$$" ???

Edit:

Donc je suppose que l'expression qui ne fonctionne pas comme prévu serait par exemple.

preg_match_all("/\bf\@ck(?:ing|er|es|s)?\b/si",$t,$m,PREG_SET_ORDER);

Qui doit trouver f@ck en $t

Mise à JOUR:

C'est mon utilisation, il suffit de mettre; si il y a des matchs en $m de les remplacer par "\*\*\*\*", ce bloc entier est à l'intérieur d'une boucle à travers chaque mot dans le dictionnaire, $f est le dictionnaire de word et d' $t d'entrée

$f = preg_quote($f);
preg_match_all("/\b$f(?:ing|er|es|s)?\b/si",$t,$m,PREG_SET_ORDER);
if (count($m) > 0) {
     $t = preg_replace("/(\b$f(?:ing|er|es|s)?\b)/si","\*\*\*\*\*",$t);
}

Mise à JOUR: Voici, l' var_dump:

preg_quote($f) = string(5) "a\$\$"
$t = string(18) "You're such an a$$"
expression = string(29) "/\ba\$\$(?:ing|er|es|s)?\b/si"

Mise à JOUR: C'est seulement quand les mots de la fin d'un symbole. J'ai testé "a$$hole" et c'est très bien, mais "a$$" ne fonctionne pas.

UNE AUTRE MISE À JOUR: Essayez cette version simplifiée, $words être un make-shift dictionnaire

$words = array("a$$","asshole","a$$hole","f@ck","f#ck","f*ck");
$text = "Input whatever you feel like here eg. a$$";

foreach ($words as $f) {
   $f = preg_quote($f,"/");
   $text = preg_replace("/\b".$f."(?:ing|er|es|s)?\b/si",
                         str_repeat("*",strlen($f)),
                        $t);
}

Je devrais attendre de voir "Input whatever you feel like here eg. \*\*\*" suite.

163voto

tchrist Points 47116

Ne peut pas être fait

Je suis désolé, mais ce "problème" est vraiment impossible à résoudre. Considérez-les:

  • ꜰᴜᴄᴋ est U + A730.1D1C.1D04.1D0B, "\ N {LETTRE LATINE PETIT CAPITAL F} \ N {LETTRE LATINE PETIT CAPITAL U} \ N {LETTRE LATINE PETIT CAPITAL C} \ N {LETTRE LATINE PETIT CAPITAL K}"
  • ᶠᵘᶜᵏ est U +1DA0.1D58.1D9C.1D4F, "\ N {LETTRE MODIFICATEUR PETIT F} \ N {LETTRE MODIFICATEUR PETIT U} \ N {LETTRE MODIFICATRICE PETIT C} \ N {LETTRE MODIFICATRICE PETIT K}" N

3voto

todofixthis Points 4206

\b vérifie une limite de mot. Selon http://www.regular-expressions.info/wordboundaries.html:

Il y a trois différentes positions considérées comme des limites de mots:

  • Avant le premier caractère de la chaîne, si le premier caractère est un caractère de mot.
  • Après le dernier caractère de la chaîne, si le dernier caractère est un caractère de mot.
  • Entre deux caractères dans la chaîne, où l'on est un caractère de mot et l'autre n'est pas un caractère de mot.

"La parole des personnages" sont des lettres, des chiffres, et des caractères de soulignement, de sorte que la chaîne "a$$", le mot se produit après la "une", pas après le deuxième "$".

Vous aurez probablement besoin de spécifier explicitement les caractères que vous considérez être des "limites de mots" à l'aide d'une classe (par exemple, [- '"]).

2voto

Slava Points 1393

Maintenant, quand vous dites que cela ne fonctionne pas à la fin du mot, je vois le problème. $@ ou tout autre caractère spécial de ce type ne fait pas partie du mot (donc \b casse le mot après 'a' dans le cas de 'a $$' s'il n'est pas suivi par toute autre lettre de la chaîne d'entrée). Je suggère d'utiliser [^a-z] pour marquer la fin du mot pour le corriger.

 preg_match_all("/\b".$f."(?:ing|er|es|s)?[^a-z]/si",$t,$m,PREG_SET_ORDER);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X