Un utilisateur peut se connecter en tant que «utilisateur» ou en tant que «utilisateur @ domaine». Je veux seulement extraire "utilisateur" dans les deux cas. Je cherche une expression correspondante pour l'adapter, mais je me bats.

final Pattern userIdPattern = Pattern.compile("(.*)[@]{0,1}.*");
final Matcher fieldMatcher = userIdPattern.matcher("user@test");
final String userId = fieldMatcher.group(1)

UserId renvoie "user @ test". J'ai essayé différentes expressions mais il semble que rien ne correspond à mon exigence :-(

Des idées?

2
Henfo 20 nov. 2018 à 22:49

4 réponses

Meilleure réponse

Si vous utilisez le motif "(.*)[@]{0,1}.*" avec .matches(), le (.*) saisit d'abord toute la ligne, puis, lorsque l'index regex est toujours à la fin de la ligne, le motif [@]{0,1} se déclenche et correspond à la fin de la ligne, car il peut correspondre à 0 caractères @, puis .* correspond à nouveau à cet emplacement, car il correspond à tout caractère 0+. Ainsi, toute la ligne atterrit dans votre groupe 1.

Vous pouvez utiliser

String userId = s.replaceFirst("^([^@]+).*", "$1");

Consultez la démo regex.

Détails

  • ^ - début de chaîne
  • ([^@]+) - Groupe 1 (désigné par $1 dans le modèle de remplacement): 1 caractère ou plus autre que @
  • .* - le reste de la chaîne.
2
Wiktor Stribiżew 20 nov. 2018 à 19:57

Un peu de googler est venu avec ceci:

(.*?)(?=@|$)

Correspondra à tout avant un @ facultatif

1
Michael Wiles 20 nov. 2018 à 20:34

Vous avez inclus le @ comme facultatif, donc la correspondance essaie d'obtenir le nom d'utilisateur le plus long. Comme vous n'avez pas mis la restriction d'un nom d'utilisateur n'est pas autorisé à contenir des @, il correspond à la chaîne la plus longue.

Utilisez simplement:

[^@]*

Comme sous-expression correspondante pour les noms d'utilisateur (et utilisez $0 pour obtenir la chaîne correspondante)

Ou vous pouvez utiliser celui-ci qui peut être utilisé pour trouver plusieurs correspondances (et pour obtenir à la fois le partie utilisateur et partie domaine):

\b([^@\s]*)(@[^@\s]*)?\b

Le \b force votre chaîne à être liée aux limites des mots, puis le premier groupe correspond aux caractères non-espace et non - @ (n'importe quel nombre, mieux vaut utiliser + au lieu de {{X3 }} là, car les noms d'utilisateur doivent avoir au moins un caractère) suivi (facultativement) d'un @ et d'une autre chaîne de caractères non-espace et non - @). Dans ce cas, $0 correspond à toutes les adresses e-mail, $1 correspond à la partie nom d'utilisateur et $2 à la partie @domain (vous pouvez affiner uniquement la partie domaine, en ajoutant un nouvelle paire de parenthèses, comme dans

b([^@\s]*)(@([^@\s]*))?\b

Consultez la démo.

0
Luis Colorado 22 nov. 2018 à 06:25

Je suggérerais de garder les choses simples et de ne pas compter sur regex dans ce cas si vous utilisez java et que vous avez un cas simple comme vous l'avez fourni.

Vous pouvez simplement faire quelque chose comme ceci:

String userId = "user@test";

if (userId.indexOf("@") != -1)
    userId = userId.substring(0, userId.indexOf("@"));

// from here on userId will be "user".

Cela supprimera toujours le "@test" ou sautera simplement le retrait lorsqu'il n'est pas là.

L'utilisation de regex dans la plupart des cas rend le code moins maintenable par un autre développeur à l'avenir car la plupart des développeurs ne sont pas très bons avec les expressions régulières, du moins d'après mon expérience.

0
JustSomeDude 20 nov. 2018 à 20:10