2012-12-26 6 views
11

Attualmente sto facendo un sistema di notizie e commenti, ma per un po 'sono bloccato su una parte. Voglio che gli utenti possano fare riferimento ad altri giocatori sullo stile twitter come @username. Lo script sarà simile a questa: (non reale PHP, solo immaginazione scripting; 3)Controlla la parola dopo un carattere '@' in PHP

$string = "I loved the article, @SantaClaus, thanks for writing!"; 
if($string contains @){ 
    $word = word after @; 
    $check = is word in database? ... 
} 

e che per tutta la @ nome utente del nella stringa, forse fatto con un po '(). Sono bloccato, per favore aiuto.

+1

Niente di male in una regex in questa situazione, si consiglia di controllare [preg_match()] (http://php.net/man ual/en/function.preg-match.php) – Havelock

+1

Si dice che la gente lo chiami * pseudocodice * – Alexander

+1

@Alexander - Mi piace un po 'però. _Impination scripting._ "Che cosa fai per lavoro, Alex?" "_Imagination scripting._" O_o ' –

risposta

15

Questo è dove espressioni regolari sono disponibili in

<?php 
    $string = "I loved the article, @SantaClaus! And I agree, @Jesus!"; 
    if (preg_match_all('/(?<!\w)@(\w+)/', $string, $matches)) 
    { 
     $users = $matches[1]; 
     // $users should now contain array: ['SantaClaus', 'Jesus'] 
     foreach ($users as $user) 
     { 
      // check $user in database 
     } 
    } 
?> 
  1. Il / all'inizio e alla fine sono delimitatori (non preoccuparti di questi per ora).
  2. \w sta per un carattere parola, che comprende a-z, A-Z, 0-9 e _.
  3. Il (?<!\w)@ è un po 'avanzato, ma si chiama un'asserzione lookbehind negativo, e significa: "Un @ che fa non seguono un carattere di parola." Questo è così che non includi cose come gli indirizzi email.
  4. \w+ significa "uno o più caratteri di parola". Lo + è noto come quantificatore .
  5. Le parentesi intorno a \w+catturano la parte parentesi e appaiono in $matches.

regular-expressions.info sembra essere una scelta popolare di tutorial, ma ce ne sono molti altri online.

+0

+1 Per la spiegazione – m4t1t0

6

Sembra un lavoro per preg_replace_callback():.

$string = preg_replace_callback('/@([a-z0-9_]+)/', function ($matches) { 
    if ($user = get_user_by_username(substr($matches[0], 1))) 
    return '<a href="user.php?user_id='.$user['user_id'].'">'.$user['name'].'</a>'; 
    else 
    return $matches[0]; 
}, $string); 
+1

+1 Funziona sicuramente, ma probabilmente confonderà i nuovi sviluppatori. La manutenibilità è importante. Questo può essere fatto senza funzioni oscure e senza espressioni regolari. Ma 6 di uno, mezza dozzina l'altra. – DampeS8N

+1

Non sono d'accordo. Le espressioni e le funzioni regolari (anche anonime) non sono nulla di oscuro.In realtà trovo questo più chiaro (perché * l'intenzione * è immediatamente ovvio per qualcuno che conosce la lingua) rispetto alla tua soluzione. – AndreKR

+1

Vorrei che fosse vero che la maggior parte del codice era gestita da persone che capiscono la lingua. Potresti pensare che non è colpa tua se i tuoi successori non conoscono la lingua, ma tutto ciò che conta allora è se riescono a capire il codice o meno. Ma sono d'accordo, tutti dovrebbero sapere queste cose. – DampeS8N

3

considerare di utilizzare le API di Twitter per prendere il nome utente dal testo: https://github.com/twitter/twitter-text-js

+0

Forse un po 'pesante per OP, ma +1 per considerare una soluzione esistente. –

2

Ecco un'espressione che abbineremo quello che ti serve, ma non cattura indirizzi e-mail:

$str = '@foo I loved the article, @SantaClaus, thanks for writing to [email protected]'; 
preg_match_all('/(^|[^a-z0-9_])(@[a-z0-9_]+)/i', $str, $matches); 
//$matches[2][0] => @foo 
///$matches[2][1] => @SantaClause 

Come è possibile vedere: [email protected] non viene catturato, ma le corde @pippo e @SantaClaus sono ...

Problemi correlati