2017-07-13 40 views
1

我有大量的ASCII文本文件和我列出了每個的內容使用下面的代碼:查找/ PHP替換文本的一部分轉換爲HTML

<?php 
$file = $_GET['file']; 
$orig = file_get_contents($file); 
$a =htmlentities($orig); 
echo $a; 
?> 

在每個文本的一些字符串ASCII文件是對其他文件的文件名稱的引用,我試圖查找並使用超鏈接替換爲該文件。

例如,文本文件可能被稱爲「LAB_E143.txt」它看起來像這樣:

LAB_E143: 
     LDX $#FF   ; load X with $FF 
     JSR LAB_E151  ; jump to this location 

什麼,我試圖找到&替換與「LAB_」開頭引用(例如LAB_E151在上面的例子中),以便它顯示文本作爲超鏈接與A HREF:

http:\\capture.php?file=lab_e151.txt 

點擊該鏈接,然後將顯示特定的文本文件的內容等。 所有參考文獻均以「LAB_」開頭,後跟4個可變字符

我試過了str_replace,但我每次都在努力分析4個變量字符。

任何幫助/指針十分讚賞

+0

您最初試圖獲得首發的文件名列表用LAB_還是你已經有這個清單?之後,您是否嘗試顯示這些文件供用戶點擊查看內容? – Mic1780

+0

嗨 - 我已經有文件列表,所有文件都以'LAB_xxxx.txt'開頭 - 如果用戶選擇LAB_E143作爲例子,並且該文件內部是LAB_E151的引用,那麼我希望文本LAB_E151是可點擊的,以便用戶然後可以讀取該文件的內容。 – TimJ

回答

0

您應該使用正則表達式這種情況。正如戰慄所提到的,preg_replace_callback應該是用於此目的的最佳功能。

  1. 檢測的所有引用與以下正則表達式:/LAB_(?<id>\S{4})/
  2. 寫一個函數與<a>標籤

這就是它取代了比賽。

$text = 'LAB_8435 Lorem ipsum dolor sit amet. LAB_8337 Amet.'; 

$formattedText = preg_replace_callback('/LAB_(?<id>\S{4})/', function ($matches) { 
    return '<a href="/capture.php?id='.$matches[1].'">'.$matches[0].'</a>'; 
}, $text); 

echo $formattedText; 
+0

非常感謝回覆,非常感謝。 – TimJ

+0

沒問題。我現在稍微改進了答案,如果你能接受答案,會很好。 –

+0

非常棒 - 真的,謝謝。事實上,感謝所有的迴應。第一次使用Stackoverflow.com,我被你們吹走了。非常感激。 – TimJ

0

警告:要顯示從特定文件夾中的文件 - 確保用戶無法與提供的字符串(文件白名單,文件名消毒)更改路徑,因爲這將有可能做一些認真的損傷。

我建議不要提供鏈接與包含文件名直接相關的線索。相反/capture.php?file=lab_e151.txt你可能有/capture.php?id=e151,然後是這樣的:

$id = isset($_GET['id']) ? $_GET['id'] : ''; //in php7: $id = $_GET['id'] ?? ''; 
if (!preg_match('/[0-9A-Za-z]{4}/', $id)) { die('Invalid link'); } 
$file = 'lab_' . $id . '.txt'; 

//... 

$convertToLink = function ($matches) { 
    return '<a href="/capture.php?id=' . strtolower($matches[1]) . '">' . $matches[0] . '</a>'; 
}; 

$code = preg_replace_callback('/LAB_([0-9A-Za-z]{4})/', $convertToLink, $string); 

echo '<pre>' . $code . '</pre>'; 

如果這4個字符是十六進制數,那麼你可以使用這個模式來代替:/LAB_([0-9A-Fa-f]{4})/

+0

非常感謝您的回覆,會給你一個答案。非常感謝 – TimJ

+0

+1關於消毒文件路徑。如果你以前沒有這樣做,一個相當快速/簡單/ hacky的方法:$ trustedPath = realpath('../ somewhere /'); $ untrustedPath = realpath($ _ UNTRUSTED ['path']); if($ untrustedPath === false || substr(($ untrustedPath),0,strlen($ trustedPath))!== $ trustedPath)die(); – wally