Bunun için regex kullanabilir miyim?

3 Cevap php

Bu regex ile mümkün mü?

Ben bir dosya var ve bir '@' dosyasında bulunursa, sonra metin '@' ile '@' '@' sonra aynı ada sahip dosya ile değiştirilmesi gereken.

File1: "this text is found in file1"
File2: "this file will contain text from file1: @file1".
File2 after regex: "this file will contain text from file1: this text is found in file1".

Ben php ile bunu isteyen ve ben gebelik işlevi ereg daha iyi olduğunu duydum, ama ne olursa olsun işleri benimle gayet =)

Thanks a lot!

EDIT:

Bu bir @ tüm oluşumları geçirdi önce bağlamak için hangi dosyaları bilmeden dosya2'nin bakar ki, programlanabilir vardır :)

3 Cevap

First of all the grammar of your templating is not a very good one becuase the parser may not exactly sure when will the file name ends. My suggestion would be that you change to the one that can better detect the boundry like {@:filename}.

Her neyse, ben aşağıda vereceğim kod soru izler.

<?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);

Bu olacak döndürür === {@ content of: file1} ~ {@ content of: file2} === .

The program will replace all the regex match with the replacement returned from the result of the given function name. In this case, the callback function is ReplaceByFileContent in which the file name is extract from the group #1 in the regex.

Benim kod kendini belgelenmiş olduğuna inanıyorum ancak herhangi bir sorunuz varsa, bana sorabilirsiniz.

Ben yardımcı olur umarım.

PHP'nin fonksiyonları str_pos ve str_replace daha büyük dosyaları veya dizeleri ile arama yaparken kullanmak daha iyidir. ;)

Daha temiz:

<?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!

?>

regex ile test: http://www.spaweditor.com/scripts/regex/index.php