2009-11-23 85 views
1

這是可能的正則表達式?我可以使用正則表達式嗎?

我有一個文件,如果在該文件中找到'@','@'後帶'@'的文本將替換爲與'@'同名的文件。 。

File1:「file1 found in file1」
File2:「此文件將包含來自file1:文件1的文本」。
正則表達式後的File2:「該文件將包含來自file1的文本:該文本位於file1中」。

我想用PHP來做到這一點,我聽說預浸功能比額日格好,但無論工作,我無所謂=)

非常感謝!

編輯:

它進行編程,使其看起來通過文件2不知道哪些文件來連接它已經通過的所有出現了前@ :)

回答

2

首先你的模板的所有語法是不是一個很好的一個監守解析器可能並不完全知道何時會文件名字結束。 我的建議是,您可以更改爲可以更好地檢測邊界{@:filename}的邊界。

無論如何,下面給出的代碼跟隨你的問題。

<?php 

// RegEx Utility functions ------------------------------------------------------------------------- 

function ReplaceAll($RegEx, $Processor, $Text) { 
    // Make sure the processor can be called 
    if(!is_callable($Processor)) 
     throw new Exception("\"$Processor\" is not a callable."); 

    // Do the Match 
    preg_match_all($RegEx, $Text, $Matches, PREG_OFFSET_CAPTURE + PREG_SET_ORDER); 

    // Do the replacment 
    $NewText = ""; 
    $MatchCount = count($Matches); 
    $PrevOffset = 0; 
    for($i = 0; $i < $MatchCount; $i++) { 
     // Get each match and the full match information 
     $EachMatch = $Matches[$i]; 
     $FullMatch = is_array($EachMatch) ? $EachMatch[0] : $EachMatch; 
     // Full match is      each match if no grouping is used in the regex 
     // Full match is the first element of each match if grouping is used in the regex. 

     $MatchOffset  = $FullMatch[1]; 
     $MatchText  = $FullMatch[0]; 
     $MatchTextLength = strlen($MatchText); 
     $NextOffset  = $MatchOffset + $MatchTextLength; 

     // Append the non-match and the replace of the match 
     $NewText .= substr($Text, $PrevOffset, $MatchOffset - $PrevOffset); 
     $NewText .= $Processor($EachMatch); 

     // The next prev-offset 
     $PrevOffset = $NextOffset; 
    } 
    // Append the rest of the text 
    $NewText .= substr($Text, $PrevOffset); 

    return $NewText; 
} 

function GetGroupMatchText($Match, $Index) { 
    if(!is_array($Match)) 
     return $Match[0]; 

    $Match = $Match[$Index]; 
    return $Match[0]; 
} 

// Replacing by file content ----------------------------------------------------------------------- 

$RegEx_FileNameInText  = "/@([a-zA-Z0-9]+)/"; // Group #1 is the file name 
$ReplaceFunction_ByFileName = "ReplaceByFileContent"; 
function ReplaceByFileContent($Match) { 
    $FileName = GetGroupMatchText($Match, 1);  // Group # is the gile name 

    // $FileContent = get_file_content($FileName); // Get the content of the file 
    $FileContent = "{@ content of: $FileName}"; // Dummy content for testing 

    return $FileContent; // Returns the replacement 
} 

// Main -------------------------------------------------------------------------------------------- 

$Text = " === @file1 ~ @file2 === "; 
echo ReplaceAll($RegEx_FileNameInText, $ReplaceFunction_ByFileName, $Text); 

這將返回=== {@ content of: file1} ~ {@ content of: file2} ===

該程序將替換所有的正則表達式匹配與給定的函數名稱的結果返回的替換。 在這種情況下,回調函數是ReplaceByFileContent,其中文件名是從正則表達式的組#1中提取的。

我相信我的代碼是自我記錄的,但如果您有任何問題,可以問我。

希望我幫忙。

+0

哇一個很好的答案,謝謝! – Johannes 2009-11-23 19:16:51

2

PHP的原生功能str_posstr_replace在搜索較大的文件或字符串時最好使用。 ;)

+0

str_pos在@出現很多事件時不起作用。 – Johannes 2009-11-23 17:14:49

1

更清潔:

<?php 

$content = file_get_content('content.txt'); 
$m = array(); 
preg_match_all('`@([^\s]*)(\s|\Z)`ism', $content, $m, PREG_SET_ORDER); 
foreach($m as $match){ 
    $innerContent = file_get_contents($match[1]); 
    $content = str_replace('@'.$match[1], $innerContent, $content); 
} 
// done! 

?> 

正則表達式與測試:http://www.spaweditor.com/scripts/regex/index.php

+0

謝謝!但它必須進行編程,以便通過file2查看,而不必知道哪些文件在經歷了所有的@ :) – Johannes 2009-11-23 16:57:31

+0

之前進行連接,以及給出的示例以及您的文章沒有提及@的多次出現。讓我更新。 – mauris 2009-11-24 02:58:21

+0

好吧,這是一個更好的更清潔。它會從@檢測空格字符,EOL或文本結尾。 – mauris 2009-11-24 03:07:43

相關問題