Regex ne permet que les caractères alphanumériques, virgule, trait d'Union, soulignement et point-virgule

j'ai déjà un peu de code qui fonctionne, mais j'ai besoin de quelqu'un pour m'expliquer pourquoi ça fonctionne si c'est possible!

J'utilise PHP pour remplacer n'importe quoi dans une chaîne de caractères si ce n'est pas a-z, A-Z, 0-9, une virgule, un point-virgule, un underscore ou un trait d'Union (qui devrait finalement représenter soit un nom d'utilisateur simple, soit une liste séparée par virgule/point-virgule de noms d'utilisateurs).

Les ouvrages suivants:

$data = preg_replace('/[^,;a-zA-Z0-9_-]/s', '', $data);

mais ce qui suit ne fait pas:

$data = preg_replace('/[^a-zA-Z0-9_-,;]/s', '', $data);

Pourquoi cela ne fonctionne que lorsque la virgule et le point-virgule au début? Les mettre à la fin semble casser les choses (c'est ce que j'ai essayé au début quand je suis tombé sur /[^A-zA-Z0-9_-]/S.

de plus, j'utilise ce qui suit pour couper tout fuite point-virgule (au pluriel) ou virgule (au pluriel) et quelqu'un pourrait-il Suggérer une façon plus efficace et/ou élégante de le faire?:

if(preg_match('/;$/', $data))
{
    $data = rtrim($data, ';' );
}
if(preg_match('/,$/', $data))
{
    $data = rtrim($data, ',' );
}

Merci pour toute aide :)

17
demandé sur Robin 2012-02-17 22:17:50

3 réponses

ce n'est pas la virgule et le point-virgule qui causent votre problème, c'est le trait d'Union. Regardez les parties de votre classe de personnages et considérez ce qu'elles signifient:

0-9 # Anything from '0' to '9', meaning 0, 1, 2, ... 9
A-Z # Anything from 'A' to 'Z', meaning A, B, C, ... Z
_-, # Anything from '_' to ',', meaning...uh...hmmm.

Il n'y a pas de nette progression de _,, donc le moteur regex n'est pas sûr de ce qu'il doit en faire. Dans les classes de caractères, si vous voulez qu'un trait d'Union soit interprété littéralement, il doit être au début ou à la fin de la classe (ou échappé avec un antislash). Donc n'importe lequel de ces travail:

[^,;a-zA-Z0-9_-]
[^-,;a-zA-Z0-9_]
[^a-zA-Z0-9_\-,;]

en ce qui concerne le découpage de la fin, vous pouvez faire tout cela en un seul regex remplacer:

$data = preg_replace('/[^,;a-zA-Z0-9_-]|[,;]$/s', '', $data);
27
répondu Justin Morgan 2012-02-17 18:31:23

je crois que c'est l'emplacement du trait d'Union qui importe -- doit être au début ou à la fin pour être un trait d'Union (littéral), sinon il est utilisé pour définir une portée.

2
répondu Devin Ceartas 2012-02-17 18:20:15

vous pouvez échapper au trait d'Union et le mettre n'importe où dans le regex comme ceci \-

en ce qui concerne les points-virgule et les virgules, essayez ceci /[,;]+$/ il devrait correspondre à n'importe quelles virgule et point-virgule à la fin, même si elles sont nombreuses.

1
répondu iDifferent 2012-02-17 18:26:55