J'essaie de créer une expression régulière afin d'extraire du texte à partir de chaînes. Je veux extraire du texte d'urls ou de messages texte normaux, par exemple:
(#[^\.]+?\.)([^\W]\w+\b)
OU
Hi #someuser.name, how are you?
Et des deux, je veux extraire exactement # someuser.name depuis le message et # someuser.id depuis l'url. Il peut y avoir beaucoup de ces chaînes à extraire de l'url et des messages.
Mon expression régulière ressemble actuellement à ceci:
endpoint/?userId=#someuser.id
Cela fonctionne bien, sauf un pour un cas et je ne sais pas comment le faire - Par exemple:
Ces chaînes NE DEVRAIENT PAS correspondre: # .id , # .id . Il doit y avoir au moins un caractère entre # et . . Un ou plusieurs espaces entre ces caractères ne doivent pas être mis en correspondance.
Comment puis-je le faire en utilisant mon expression régulière actuelle?
4 Réponses :
Vous pouvez essayer l'expression régulière suivante:
#someuser.id #someuser.name
Remarques:
\ #(\\w+)\\.(\\w+) id est uniquement composé de chiffres, vous pouvez modifier le deuxième \ w par [0-9ITED nom d’utilisateur comprend d’autres caractères que l’alphabet, des chiffres et un trait de soulignement, vous devez changer \ w en une classe de caractères avec tous les caractères autorisés définis explicitement. li >
Exemple de code:
String input = "endpoint/?userId=#someuser.id Hi #someuser.name, how are you? # .id, #.id.";
Matcher m = Pattern.compile("#(\\w+)\\.(\\w+)").matcher(input);
while (m.find()) {
System.out.println(m.group());
}
sortie:
#(\w+)\.(\w+)
C'est proche mais il devrait être possible d'utiliser des espaces en valeur entre # et. mais UNIQUEMENT s'il y a d'autres personnages. L'espace est illégal dans le "deuxième groupe" de votre exemple. Donc je peux avoir ces chaînes: # someuser.id, #some user.id MAIS je ne peux pas ceux: # .id, # .id, # someuser.i d
Aussi dans le premier mot entre # et. devrait être possible d'utiliser tous les caractères aussi spéciaux comme () - * etc
@Carath qu'en est-il de #someuser .id avec un espace juste avant le point
l'espace avant le point est possible mais pas après
@Carath pouvez-vous essayer: # ((?: * [\ w \ [\] () * -] + *) +) \. (\ W +)
C'est vraiment proche mais je ne peux pas utiliser maintenant des personnages comme! @% par exemple: # certains% user .id ne correspondent pas, mais lorsque supprimez '%', c'est correct.
@Carath ajoutez-les simplement entre les crochets de l'expression régulière et gardez le - avant le crochet fermant
@Carath # ((?: * [\ w \ [\] () * @!% & {} <> ^ & $ -] + *) +) \. (\ W +)
N'y a-t-il pas quelque chose de plus court pour marquer tous ces caractères au lieu de les ajouter tous?
@Carath vous pouvez écrire ce bloc comme [^ #.] il est plus court, vous acceptez tout sauf l'espace, # et. dans cette partie
@Allan qui correspondrait également à la virgule dans le deuxième cas de test ( # someuser.name, au lieu de # someuser.name ). Dans l'ensemble, les exigences de la question ne sont pas assez claires pour savoir quels caractères sont et ne sont pas autorisés.
@Kevin Cruijssen me laisse le diviser en 2 groupes, le premier groupe est tout entre # et point, le second groupe est tout entre point et TOUT caractère spécial. Premier groupe: il est possible d'avoir tous les caractères spéciaux bien sûr au lieu de points et #. Il est possible d'avoir des espaces mais PAS seulement des espaces et "quelque chose" à l'intérieur peut ne pas être vide donc "# .id" n'est pas non plus possible. Le deuxième groupe peut ne pas avoir de caractères spéciaux - seules les lettres et les chiffres sont possibles ici, également l'espace n'est pas possible dans le deuxième groupe. Si le deuxième groupe a un caractère spécial, cela signifie qu'il y a la fin de la correspondance
endpoint/?userId=#someuser.id -> group[0]=someuser and group[1]=id
Ce n'est pas ce que je veux sans raison. Je ne veux qu'un seul groupe et il devrait être possible d'utiliser des espaces en valeur entre # et. mais UNIQUEMENT s'il y a d'autres personnages. L'espace est illégal dans le "deuxième groupe" de votre exemple. Donc je peux avoir ces chaînes: # someuser.id, #some user.id MAIS je ne peux pas ceux: # .id, # .id, # someuser.i d
pouvez-vous essayer ceci (# \ w +. + \ w *. \ w +) vous obtiendrez # someuser.id, # some user.id mais pas # .id, # .id
Les exigences redéfinies sont:
#A.B Un peut être n'importe quoi, sauf pour les espaces uniquement, ni contenir # ou . B ne peut être que des lettres ou des chiffres ASCII normaux Conversion de ces exigences en une (possible) regex:
Input: "endpoint/?userId=#someuser.id Hi #someuser.name, how are you? # .id #.id %^*#@*(.H(@EH Ok, # some spaces here .but none here #$pâ¬Â©Ã¯@l.$pâ¬Â©Ã¯@l that should do it.." Outputs: "#someuser.id" "#someuser.name" "#@*(.H" "# some spaces here .but"
Explication:
String input = "endpoint/?userId=#someuser.id Hi #someuser.name, how are you? # .id #.id %^*#@*(.H(@EH Ok, # some spaces here .but none here #$pâ¬Â©Ã¯@l.$pâ¬Â©Ã¯@l that should do it..";
System.out.println("Input: \""+ input + '"');
System.out.println("Outputs: ");
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("#[^.#]+((?<!#\\s+)\\.)[A-Za-z0-9]+")
.matcher(input);
while(matcher.find())
System.out.println('"'+matcher.group()+'"');
C'est vraiment proche de ce que je veux mais il y a une correspondance qui devrait être mise en correspondance, par exemple: # .id. Il ne devrait pas être possible d'utiliser dans 'A' un seul espace donc # [space] [space] .id correspond maintenant comme correct mais ne devrait pas l'être
@Carath # [space] [space] .id ne correspond pas à mon code ci-dessus .. Ceci est empêché par le + après \\ s code>. Êtes-vous en train de dire que # [space] [space] .id est autorisé mais pas # [space] .id ? Dans ce cas, vous pouvez supprimer le + . Ou dites-vous que # [tab] .id doit correspondre, mais pas # [space] .id , auquel cas le \\ s code > (les espaces et tabulations (et les retours à la ligne si l'option multiligne est activée, ce qui n'est pas le cas ici)) peuvent être remplacés par ``? Je ne comprends pas vraiment votre commentaire, pour être honnête.
@KevinCruijssen: oui sans exigences claires, il n'est pas facile d'atteindre "the" bonne réponse
Vous pouvez utiliser
#someuser.id #someuser.name
Voir la démo regex a> et son graphique :
Détails
# - un symbole # [^. #] * - zéro ou plusieurs caractères autres que . et # [^. # \\ s] - tout caractère sauf . , # et les espaces [^ #.] * - - zéro ou plusieurs caractères autres que . et # \. - un point \ w + - 1 caractères ou plus de mots (lettres, chiffres ou _ ). String s = "# #.id\nendpoint/?userId=#someuser.id\nHi #someuser.name, how are you?";
String regex = "#[^.#]*[^.#\\s][^#.]*\\.\\w+";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
System.out.println(matcher.group(0));
}
Sortie:
String regex = "#[^.#]*[^.#\\s][^#.]*\\.\\w+";
C'est ce que je voulais, merci :)
Essayez
String regex = "# [^.] * [^. \\ s] [^.] * (?: \\. \\ w +) *";. OuString regex = "# [^.] * [^. \\ s] [^.] * \\. \\ w +";Veuillez vérifier la deuxième expression régulière du commentaire ci-dessus si vous voulez faire correspondre
#et 2 parties séparées par.après.@ WiktorStribiżew si proche! Il n'y a qu'une seule chaîne qui ne devrait pas être mise en correspondance mais c'est par exemple: # # .id Le caractère '#' est illégal, le hachage signifie seulement qu'il y a une balise à faire correspondre mais il ne peut pas être utilisé comme l'un des caractères spéciaux disponibles
Alors, essayez d'exclure
#du premier groupe,"# [^. #] * [^. # \\ s] [^ #.] * \\. \\ w +" < / code>, voir regex101.com/r/Qv8Qnl/1@ WiktorStribiżew parfait! =) Maintenant, tout fonctionne correctement, merci :)
Heureux de vous aider, a publié une réponse ci-dessous .