كيف تلف الكلمات أو تسلسل الكلمات التي لم يتم لفها بالفعل؟
-
29-09-2019 - |
سؤال
أحاول لف تسلسل الكلمات والكلمات من قائمة معينة مع preg_replace. إنه يعمل تقريبًا ، ولكن هناك بعض حالات الاستخدام لا ، ولا يمكنني تحديد كيفية ذلك.
على سبيل المثال أفعل هذا:
// sort by descending length
usort($this->_keywords, function($a,$b){return(strlen($a)<strlen($b));});
// wrapper is -%string%-
foreach ($this->_keywords as $keyword) {
$value = preg_replace('/((?!-)' . $keyword . '(?!-))/i', str_replace('%string%', '\1', $this->_wrapper), $value);
}
من قائمة الكلمات الرئيسية هذه:
- لوريم
- Ipsum
- الجلوس أميت
- لا شيء
- سيد
- سيد enim
أود أن يؤدي إلى:
-لور- -PSUM- دولور -أييت-، incectetur adipiscing النخبة. Phasellus Rhoncus Venenatis Orci Sed Porta. SED NON DOLOR EROS. Sugfendisse ماسا -أييت- Nulla egestas facilisis. Cras Fringilla ، Leo Ac Ullamcorper Semper ، Urna Eros Pretium Lectus ، NEC Rhoncus ligula Risus Eu Velit. Nulla Eu Dapibus Magna. سيد مركبة تريستيك لاكينيا. Maecenas Tincidunt Metus في Urna نتيجة NEC Congue Libero Iaculis. نولا هوسيليسي. Phasellus -اليد-Sem ut Risus Mattis Accumsan EU -صوفيس-. Pellentesque Maltant Morbi Tristique Senectus et netus et malesuada fames ac turpis egestas. SuperNdisse id est Velit ، الاتحاد الأوروبي Cursus Quam. Vivamus lacinia euismod pretium.
أيه أفكار؟
المحلول 2
أخيرا حلت مشاكلي باستخدام \b
metacharacters التي تتوافق مع حدود كلمة.
public function filter($value)
{
usort($this->_keywords, function($a,$b){return(strlen($a)<strlen($b));});
foreach ($this->_keywords as $keyword) {
$value = preg_replace(
'/((?<!-)('.$keyword.'\b)(?!\-))/i',
str_replace('%string%', '\2', $this->_wrapper) . '\3',
$value
);
}
return $value;
}
نصائح أخرى
الأسهل هو الاستخدام preg_replace_callback()
, ، ومطابقة الكلمات التي تم لفها بالفعل ، وكل كلمة رئيسية. عندما تكون المباراة عبارة عن كلمة ملفوفة ، ما عليك سوى إرجاعها غير المعدلة. لا حاجة للنظر الإشكالي.
function compare_length($a, $b) {
return strlen($a) < strlen($b);
}
function build_regex($keywords) {
usort($keywords, 'compare_length');
$pieces []= '/(?<wrapped>-[\w\s]*-)|(?<keyword>';
for ($i = 0; $i < count($pieces); $i++) {
if ($i > 0) $pieces []= '|';
$pieces []= preg_quote($keywords[$i], '/');
}
$pieces []= ')/';
return implode("", $pieces);
}
function wrap_callback($match) {
if (!empty($match['wrapped'])) {
return $match['wrapped'];
}
return "-{$match['wrapped']}-";
}
function wrap($text, $keywords) {
$regex = build_regex($keywords);
return preg_replace_callback($regex, 'wrap_callback');
}