Regex para substituir condicionalmente as hashtags do Twitter por hiperlinks
Pergunta
Estou escrevendo um pequeno script PHP para pegar as últimas meia dúzia de atualizações de status do Twitter de um feed de usuário e formatá -las para exibição em uma página da web. Como parte disso, preciso de uma regex substituir para reescrever hashtags como hiperlinks para pesquisar.twitter.com. Inicialmente, tentei usar:
<?php
$strTweet = preg_replace('/(^|\s)#(\w+)/', '\1#<a href="http://search.twitter.com/search?q=%23\2">\2</a>', $strTweet);
?>
(Tirado de https://gist.github.com/445729)
No decorrer dos testes, descobri que o #Test é convertido em um link no site do Twitter, no entanto, o #123 não é. Depois de um pouco de check -in na internet e brincando com várias tags, cheguei à conclusão de que uma hashtag deve conter caracteres alfabéticos ou um sublinhado nele em algum lugar para constituir um link; Tags com apenas caracteres numéricos são ignorados (presumivelmente para parar as coisas como "Boa apresentação Bob, slide #3 foi a minha favorita!" Por estar vinculado). Isso torna o código acima incorreto, pois ele converterá com prazer nº 123 em um link.
Eu não fiz muito Regex há algum tempo, então, na minha enferrujada, criei a seguinte solução PHP:
<?php
$test = 'This is a test tweet to see if #123 and #4 are not encoded but #test, #l33t and #8oo8s are.';
// Get all hashtags out into an array
if (preg_match_all('/(^|\s)(#\w+)/', $test, $arrHashtags) > 0) {
foreach ($arrHashtags[2] as $strHashtag) {
// Check each tag to see if there are letters or an underscore in there somewhere
if (preg_match('/#\d*[a-z_]+/i', $strHashtag)) {
$test = str_replace($strHashtag, '<a href="http://search.twitter.com/search?q=%23'.substr($strHashtag, 1).'">'.$strHashtag.'</a>', $test);
}
}
}
echo $test;
?>
Funciona; Mas parece bastante longo pelo que faz. Minha pergunta é: existe um único preg_replace semelhante ao que recebi do gist.github que reescreverá condicionalmente hashtags em hiperlinks apenas se eles não contiverem apenas números?
Solução
(^|\s)#(\w*[a-zA-Z_]+\w*)
Php
$strTweet = preg_replace('/(^|\s)#(\w*[a-zA-Z_]+\w*)/', '\1#<a href="http://twitter.com/search?q=%23\2">\2</a>', $strTweet);
Essa expressão regular diz um # seguido por 0 ou mais caracteres [A-ZA-Z0-9_], seguido por um caractere alfabético ou um sublinhado (1 ou mais), seguido por 0 ou mais caracteres do Word.
http://rubular.com/r/opnx6qc4sg <- teste aqui.
Outras dicas
Na verdade, é melhor procurar personagens que não sejam permitidos em uma hashtag, caso contrário, tags como "#Trentemøller" não funcionam.
O seguinte funciona bem para mim ...
preg_match('/([ ,.]+)/', $string, $matches);
Eu criei isso: /(^|\s)#([[:alnum:]])+/gi
Encontrei diabos responda Para trabalhar, embora o Regex tenha adicionado um espaço em branco no início da hashtag, então eu removi a primeira parte:
(^|\s)
Isso funciona perfeitamente para mim agora:
#(\w*[a-zA-Z_0-9]+\w*)
Exemplo aqui: http://rubular.com/r/ds2qyzp45n