我可以使用正则表达式吗?

时间:2009-11-23 16:37:34

标签: php regex

这是否可以使用正则表达式?

我有一个文件,如果在文件中找到'@','@'后带有'@'的文本将替换为与'@'后面同名的文件。

File1:“此文本位于file1”中 File2:“此文件将包含来自file1的文本:@ file1” 正则表达式后的File2:“此文件将包含来自file1的文本:此文本位于file1”。

我希望用php做这个,我听说preg函数比ereg更好,但无论什么工作对我都没关系=)

非常感谢!

编辑:

必须对它进行编程,以便它在查看文件2之前不知道要连接哪些文件,然后才能完成所有出现的@:)

3 个答案:

答案 0 :(得分:2)

当您搜索较大的文件或字符串时,最好使用PHP的本机函数str_posstr_replace。 ;)

答案 1 :(得分: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中提取的。

我相信我的代码是自我记录的,但如果您有任何疑问,可以问我。

希望我能帮忙。

答案 2 :(得分: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

测试正则表达式