2010-03-02 5 views
0

Je voudrais utiliser des expressions régulières pour extraire uniquement @patrick @michelle de la phrase suivante:expression régulière pour extraire les symboles @name de Tweet

@patrick @michelle we having diner @home tonight do you want to join? 

Note: @home ne devrait pas être inclure dans le résultat parce que, ce n'est pas au début de la phrase et n'est pas suivi d'un autre @name.

Toute solution, conseil, commentaire sera vraiment apprécié.

+2

Si '@ home' * * ont été suivi par un autre' @name ', les deux valeurs * seraient-elles considérées comme des noms, ou seulement le premier? Savez-vous que vos règles ne correspondent pas à la façon dont les gens utilisent Twitter? –

Répondre

4
/(?:(?:@\S+\s+)+|^)@\S+/g 

Il correspond d'abord soit un « @ » suivi par de nombreux caractères non-espace, ou le début de la ligne, puis une autre et correspond à « @ » suivi par de nombreux caractères non-espace.

Notez qu'il est courant sur Twitter que @name est précédé de RT, apparaît au milieu ou à la fin du tweet, par ex. http://twitter.com/ceetee/statuses/9874073403. Fondamentalement, vous ne pouvez pas distinguer si un @ nom est vraiment un nom utilisant simplement RegEx ou même un analyseur. Le meilleur pari est de vérifier si http://twitter.com/name 404 ou non.

+0

Cela semble bien fonctionner mais seulement pour 2. Comment l'étendre pour correspondre à n @name au début de la phrase. Entrée: @patrick @michelle @john @Ted nous avons diner @home ce soir voulez-vous rejoindre? – Joey

+0

@Joey: Voir mise à jour. – kennytm

+0

Merci Kenny, c'est exactement ce que je veux Implémentation en python Importer re msg = 'vient ici' re.findall ('(?: (?: @ \ S + \ s +) + | ^) @ \ S +' , msg) – Joey

0

Essayez cette expression régulière:

/^\s*@(\w+)\[email protected](\w+)/ 

\s désigne un espace et un \w caractères de mot.

+0

@Gumbo: Je pense que Joey peut être après quelque chose d'un peu plus robuste ... votre expression rationnelle ne correspondrait pas s'il n'y avait qu'un seul nom – Zaid

0

Tant qu'il commence par un @ et continue avec ceux-ci cela le fera, je l'ai testé dans poweshell donc certains moteurs regex sont un peu différents. Cela devrait également prendre n noms au début de la ligne

«^((@ \ w +) \ s) + »

+0

Vous devez ajouter un espace de fin à la chaîne avant d'utiliser cette RE, cependant , pour gérer le cas où la chaîne se termine par '@ foo'. –

+0

oui si la chaîne se termine par un at. le \ s shuld be \ s * – rerun

0

Peut-être quelque chose comme ça, mais vous devrez partager sur quoi que ce soit des espaces dans la groupe correspondant pour extraire plusieurs ID.

/^\s*(@\w+\s+)*\s+.*$/ 
0

Vous avez étiqueté votre message C#, donc je suppose que vous pouvez utiliser l'implémentation .NET Regex. En utilisant .NET, l'expression rationnelle suivante fera:

(?<![^@]\w+\s+)(@\w+) 

Cela correspond à aucun des mots commençant par @, qui n'ont pas un mot sans @ devant eux. Notez que "dinner @home @ 20pm" va encore le casser, cependant.

Voir here pour plus de détails.

1

Eh bien, tout d'abord je pensais que cela a échoué parce que je regardais les groupes qui sont retournés:

>>> tw = re.compile(r"^((@\w*)\s+)*") 
>>> tw.findall(tweet) 
[('@michelle ', '@michelle')] 
>>> tw.match(tweet).groups() 
('@michelle ', '@michelle') 

Notez que les groupes ne conservent que la dernière valeur pour tout groupe dans la re.Mais si vous prenez juste un groupe(), vous obtenez toute la chaîne trouvée:

>>> tw.match(tweet).group() 
'@patrick @michelle ' 

pour des grimaces, je vais essayer pyparsing:

>>> from pyparsing import Word, printables, OneOrMore 
>>> atName = Word("@",printables) 
>>> OneOrMore(atName).parseString(tweet).asList() 
['@patrick', '@michelle'] 
0

pour PHP

/^\s*@(\w+)\[email protected](\w+)/ 

Merci KennyM

en python

msg = '@patrick @michelle we having diner @home tonight do you want to join?' 
import re 
re.findall('(?:(?:@\S+\s+)+|^)@\S+', msg) 

Cela fonctionne avec 1 ou n @name au début de la phrase.

Merci à tous pour les réponses rapides.

0

En Perl, vous pouvez exploiter le /g match plus-que-fois modificateur combiné avec le zéro largeur \G où-on-gauche hors affirmation et contexte de liste, donc:

my $str = '@patrick @michelle we having diner @home tonight do you want to join?'; 
my @matches = ($str =~ m/\G(\@\w+)\s*/g); 

print join(', ', @matches) . "\n"; 

Cela devrait être robuste sur un nombre quelconque de chaînes @ initiales.

0

Pour Python check out: http://github.com/BonsaiDen/AtarashiiFormat
Il vous donnera également les liens et les étiquettes. Et, méfiez-vous de l'utilisation d'une simple regex, vous vous retrouverez avec un gros bordel, comme je l'ai fait avant de convertir la bibliothèque textuelle de Twitter.

0

Pour C# Je ferais comme suit:

@ ([A-Za-z0-9-_ &;] +)

Questions connexes