2011-10-31 2 views
1

d'une chaîne comme:Comment trouver toutes les instances de @ [XX: XXXX] dans une chaîne, puis trouver le texte environnant?

"@[19:Sara Mas] what's the latest with the TPS report? @[30:Larry Peters] can you help out here?" 

Je veux trouver un moyen de revenir dynamiquement, l'utilisateur marqué et le contenu environnant. Les résultats devraient être:

user_id: 19 
copy: what's the latest with the TPS report? 

user_id: 30 
copy: can you help out here? 

Des idées sur comment cela peut être fait avec ruby ​​/ rails? Merci

Comment est cette regex pour trouver des correspondances?

@\[\d+:\w+\s\w+\] 
+0

http://rubular.com/ – Ryanmt

+0

Rubular pourrait aider w @ [XX: XXXXX] mais pas en boucle à travers ou trouver le bon contenu environnant? –

+0

J'ai ceci pour la regex, @ \ [\ d +: \ w + \ s \ w + \] mais maintenant où vais-je? –

Répondre

1
result = subject.scan(/\[(\d+).*?\](.*?)([email protected]|\Z)/m) 

Ceci saisit l'identifiant et le contenu dans les références arrière 1 et 2 respectivement. Pour arrêter la capture, @ ou la fin de la chaîne doit être respectée.

" 
\\[   # Match the character “[” literally 
(   # Match the regular expression below and capture its match into backreference number 1 
    \\d   # Match a single digit 0..9 
     +   # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
) 
.   # Match any single character that is not a line break character 
    *?   # Between zero and unlimited times, as few times as possible, expanding as needed (lazy) 
\\]   # Match the character “]” literally 
(   # Match the regular expression below and capture its match into backreference number 2 
    .   # Match any single character that is not a line break character 
     *?   # Between zero and unlimited times, as few times as possible, expanding as needed (lazy) 
) 
(?=  # Assert that the regex below can be matched, starting at this position (positive lookahead) 
       # Match either the regular expression below (attempting the next alternative only if this one fails) 
     \@   # Match the character “\@” literally 
    |   # Or match regular expression number 2 below (the entire group fails if this one fails to match) 
     \$   # Assert position at the end of the string (or before the line break at the end of the string, if any) 
) 
" 

Ceci correspond à quelque chose commençant par @ et se terminant par la ponctuation makr. Désolé si je n'ai pas bien compris.

result = subject.scan(/@.*?[.?!]/) 
+0

Merci, juste essayé cela. Problèmes de couple. le nombre 19 ou 30 est le user.id donc il peut être de 1 à l'infini entiers longs. En outre, si la chaîne est "Quel est le problème avec les rapports @ [30: Larry Peters]" ce qui précède renvoie "" comme contenu. Existe-t-il un moyen pour le contenu d'obtenir la phrase entière où la correspondance a été faite? –

+0

Ne gère que les identifiants utilisateur à 2 chiffres. – Ryanmt

+0

@Ryanmt Je n'ai pas vu d'exemple avec un plus grand nombre de chiffres. Cette chose triviale peut simplement être corrigée avec \ d +. Merci pour le conseil cependant .. – FailedDev

2

Divisez la chaîne, puis gérez le contenu de manière itérative. Je ne pense pas qu'il faudrait plus de:

tmp = string.split('@').map {|str| [str[/\[(\d*).*/,1], str[/\](.*^)/,1]] } 
tmp.first #=> ["19", "what's the latest with the TPS report?"] 

Est-ce que cela aide?

+0

Intéressant, merci pourquoi diviser la chaîne? Ce serait bien de trouver tous les endroits où l'expression rationnelle correspond. Puis, saisissez le contenu environnant soit vers la droite jusqu'au premier signe d'un signe de ponctuation (point, point d'interrogation, point d'exclamation). Des idées? –

+1

Bien sûr, c'est possible. Je pense que c'est plus simple à déboguer, et probablement moins difficile à lire plus tard, quand vous avez oublié ce que le REGEX était censé faire. – Ryanmt

+0

Je ne sais pas ce que cela signifie, s'il vous plaît voir les réponses dans l'autre question ... –

Questions connexes