Regex لاستبدال علامات التجزئة على Twitter بشرطة تشعبية
سؤال
أنا أكتب نصًا صغيرًا لـ PHP للاستيلاء على آخر دزينة من تحديثات حالة Twitter من خلاصة المستخدم وتنسيقها للعرض على صفحة ويب. كجزء من هذا ، أحتاج إلى استبدال regex لإعادة كتابة علامات التجزئة كروابط تشعبية للبحث. twitter.com. في البداية حاولت استخدام:
<?php
$strTweet = preg_replace('/(^|\s)#(\w+)/', '\1#<a href="http://search.twitter.com/search?q=%23\2">\2</a>', $strTweet);
?>
(مأخوذ من https://gist.github.com/445729)
أثناء الاختبار ، اكتشفت أن #Test يتم تحويله إلى رابط على موقع Twitter ، ولكن #123 ليس كذلك. بعد قليل من التحقق من الإنترنت واللعب مع العديد من العلامات ، توصلت إلى استنتاج مفاده أن علامة التجزئة يجب أن تحتوي على شخصيات أبجدية أو سحرية في مكان ما لتشكيل رابط ؛ يتم تجاهل العلامات ذات الأحرف الرقمية فقط (من المفترض أن تتوقف عن أشياء مثل "عرض جيد بوب ، كانت الشريحة رقم 3 هي المفضلة لدي!" من الارتباط). هذا يجعل الكود أعلاه غير صحيح ، لأنه سيتم تحويل #123 بسعادة إلى رابط.
لم أقم بالكثير من Regex منذ فترة ، لذا في بلدي الصدفة ، توصلت إلى حل 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;
?>
إنها تعمل؛ ولكن يبدو أنه طويل إلى حد ما لما يفعله. سؤالي هو ، هل هناك preg_replace واحد مماثل لتلك التي حصلت عليها من gist.github والتي ستعيد كتابة علامات التجزئة بشكل مشروط إلى ارتباطات تشعبية فقط إذا لم تحتوي على أرقام فقط؟
المحلول
(^|\s)#(\w*[a-zA-Z_]+\w*)
بي أتش بي
$strTweet = preg_replace('/(^|\s)#(\w*[a-zA-Z_]+\w*)/', '\1#<a href="http://twitter.com/search?q=%23\2">\2</a>', $strTweet);
يقول هذا التعبير المنتظم A # متبوعًا بحرف 0 أو أكثر [A-ZA-Z0-9_] ، يليه حرف أبجدي أو سحرية (1 أو أكثر) ، تليها 0 أحرف كلمة أو أكثر.
http://rubular.com/r/opnx6qc4sg <- اختبره هنا.
نصائح أخرى
من الأفضل في الواقع البحث عن شخصيات غير مسموح بها في علامة التجزئة وإلا لن تعمل علامات مثل "#Trentemøller".
التالي يعمل بشكل جيد بالنسبة لي ...
preg_match('/([ ,.]+)/', $string, $matches);
لقد ابتكرت هذا: /(^|\s)#([[:alnum:]])+/gi
لقد وجدت غزلرز إجابه للعمل ، على الرغم من أن Regex أضاف مساحة فارغة في بداية علامة التجزئة ، لذلك قمت بإزالة الجزء الأول:
(^|\s)
هذا يعمل بشكل مثالي بالنسبة لي الآن:
#(\w*[a-zA-Z_0-9]+\w*)
مثال هنا: http://rubular.com/r/ds2qyzp45n