2010-08-18 37 views
6

Tôi có văn bản ($text) và một loạt các từ ($tags). Những từ này trong văn bản phải được thay thế bằng các liên kết đến các trang khác để chúng không phá vỡ các liên kết hiện có trong văn bản. Trong CakePHP có một phương thức trong TextHelper để làm điều này nhưng nó bị hỏng và nó phá vỡ các liên kết HTML hiện có trong văn bản. Phương pháp giả sử để làm việc như thế này:Thay thế các từ có liên kết thẻ bằng PHP

$text=Text->highlight($text,$tags,'<a href="/tags/\1">\1</a>',1); 

Dưới đây có mã hiện có trong CakePHP TextHelper:

function highlight($text, $phrase, $highlighter = '<span class="highlight">\1</span>', $considerHtml = false) { 
    if (empty($phrase)) { 
    return $text; 
    } 

    if (is_array($phrase)) { 
    $replace = array(); 
    $with = array(); 

    foreach ($phrase as $key => $value) { 
     $key = $value; 
     $value = $highlighter; 
     $key = '(' . $key . ')'; 
     if ($considerHtml) { 
     $key = '(?![^<]+>)' . $key . '(?![^<]+>)'; 
     } 
     $replace[] = '|' . $key . '|ix'; 
     $with[] = empty($value) ? $highlighter : $value; 
    } 
    return preg_replace($replace, $with, $text); 
    } else { 
    $phrase = '(' . $phrase . ')'; 
    if ($considerHtml) { 
     $phrase = '(?![^<]+>)' . $phrase . '(?![^<]+>)'; 
    } 

    return preg_replace('|'.$phrase.'|i', $highlighter, $text); 
    } 
} 

Trả lời

0

Mã này hoạt động tốt. Những gì bạn có thể cần làm là kiểm tra CSS cho <span class="highlight"> và chắc chắn rằng nó được thiết lập để một số màu sắc mà sẽ cho phép bạn phân biệt rằng nó là ánh sáng cao.

.highlight { background-color: #FFE900; } 
+0

Tôi không hỏi về đánh dấu. Vui lòng đọc câu hỏi. – Amorphous

+0

Bạn sẽ cung cấp mẫu '$ text' để xem? Mã hoạt động tốt khi tôi kiểm tra nó. Tôi có thể nói rằng có thể là '$ tags' mà bạn đang tìm kiếm để thay thế có thể tồn tại bên trong một thẻ'

0

Vô định hình - Tôi nhận thấy Gert đã chỉnh sửa bài đăng của bạn. Hai đoạn mã có phải là chính xác khi bạn đăng chúng?

Vì vậy, ngay cả khi mã gốc được thiết kế để làm nổi bật, tôi hiểu bạn đang cố gắng sử dụng lại nó để tạo liên kết - nó phải và hoạt động tốt cho điều đó (được kiểm tra là đã đăng).

HOWEVER thoát trong đoạn mã đầu tiên có thể là một vấn đề.

$text=Text->highlight($text,$tags,'<a href="/tags/\1">\1</a>',1); 

Làm việc tốt ... nhưng nếu bạn sử dụng dấu trừ hơn dấu thì dấu gạch chéo ngược sẽ biến mất như dấu thoát - bạn cần phải thoát chúng. Nếu bạn không nhận được% 01 liên kết.

Cách đúng với dấu bài phát biểu là:

$text=Text->highlight($text,$tags,"<a href=\"/tags/\\1\">\\1</a>",1); 

(Chú ý việc sử dụng \ 1 thay vì \ 1)

1

Thay thế văn bản trong HTML cơ bản là khác nhau hơn thay thế văn bản đơn giản. Để xác định xem văn bản là một phần của thẻ HTML yêu cầu bạn phải tìm tất cả các thẻ để không xem xét chúng. Regex không thực sự là công cụ cho việc này.

tôi sẽ cố gắng một trong những giải pháp sau:

  • Tìm vị trí của tất cả các từ. Làm việc từ đầu đến cuối, xác định xem mỗi phần có phải là một phần của thẻ hay không. Nếu không, hãy thêm neo.
  • Tách chuỗi thành các khối. Mỗi khối là một thẻ hoặc văn bản thuần túy. Chạy (các) bộ phận thay thế của bạn trên các khối văn bản đơn giản và lắp ráp lại.

Tôi nghĩ cái đầu tiên có thể hiệu quả hơn một chút, nhưng dễ bị lỗi lập trình hơn, vì vậy tôi sẽ để nó tùy thuộc vào bạn.

Nếu bạn muốn biết lý do tại sao tôi không tiếp cận trực tiếp vấn đề này, hãy xem tất cả các câu hỏi trên trang web về regex và HTML và cách regex không phải là trình phân tích cú pháp.

2

Bạn có thể nhìn thấy (và chạy) thuật toán này ở đây:

http://www.exorithm.com/algorithm/view/highlight

Nó có thể được thực hiện tốt hơn một chút và đơn giản với một vài thay đổi, nhưng nó vẫn không phải là hoàn hảo. Mặc dù kém hiệu quả hơn, tôi muốn giới thiệu một trong những giải pháp của Ben Doom.

Các vấn đề liên quan