php最简单的案例正则表达式替换,但回溯无法正常工作

时间:2011-03-09 00:02:01

标签: php regex preg-replace

在php中破解我认为是第二种最简单的正则表达式(从某些字符串中提取匹配的字符串,并使用它),但正则表达式分组似乎正在绊倒我。

目标

  1. 获取ls个文件,输出命令以格式化/复制文件以使其具有正确的命名格式。
  2. 调整文件副本的大小以创建缩略图。 (甚至没有处理那个步骤)
  3. 失败

    我的代码在正则表达式步骤失败,因为虽然我只想过滤除了单个正则表达式组之外的所有内容,但是当我得到结果时,它总是返回我想要的组 - 并且 - 在它之前的组,即使我绝不会要求第一个回溯组。

    以下是在线ide上代码的完整功能,可运行版本: http://ideone.com/2RiqN

    这是代码(减少了初始数据集,虽然我不希望这一点很重要):

    <?php
    
    // Long list of image names.
    $file_data = <<<HEREDOC
    07184_A.jpg
    Adrian-Chelsea-C08752_A.jpg
    Air-Adams-Cap-Toe-Oxford-C09167_A.jpg
    Air-Adams-Split-Toe-Oxford-C09161_A.jpg
    Air-Adams-Venetian-C09165_A.jpg
    Air-Aiden-Casual-Camp-Moc-C09347_A.jpg
    C05820_A.jpg
    C06588_A.jpg
    Air-Aiden-Classic-Bit-C09007_A.jpg
    Work-Moc-Toe-Boot-C09095_A.jpg
    HEREDOC;
    
    if($file_data){
        $files = preg_split("/[\s,]+/", $file_data);
        // Split up the files based on the newlines.
    }
    $rename_candidates = array();
    $i = 0;
    foreach($files as $file){
        $string = $file;
        $pattern = '#(\w)(\d+)_A\.jpg$#i';
        // Use the second regex group for the results.
        $replacement = '$2';
        // This should return only group 2 (any number of digits), but instead group 1 is somehow always in there.
        $new_file_part = preg_replace($pattern, $replacement, $string);
    // Example good end result: <img src="images/ch/ch-07184fs.jpg" width="350" border="0">
        // Save the rename results for further processing later.
        $rename_candidates[$i]=array('file'=>$file, 'new_file'=>$new_file_part);
        // Rename the images into a standard format.
        echo "cp ".$file." ./ch/ch-".$new_file_part."fs.jpg;";
            // Echo out some commands for later.
        echo "<br>"; 
        $i++;
        if($i>10){break;} // Just deal with the first 10 for now.
    }
    ?>
    

    正则表达式的预期结果:788750 代码输出的预期结果(多行):cp air-something-something-C485850_A.jpg ./ch/ch-485850.jpg;

    我的正则表达式有什么问题?对于更简单的匹配代码的建议也会受到赞赏。

2 个答案:

答案 0 :(得分:2)

只是一个猜测:

 $pattern = '#^.*?(\w)(\d+)_A\.jpg$#i';

这包括匹配中的整个文件名。否则preg_replace()实际上只会替换每个字符串的结尾 - 它只在实际匹配的部分上应用$replacement表达式。

答案 1 :(得分:1)

扫描目录和扩展

你知道吗?在php中更简单的方法是使用scandir和explode combo

  $dir = scandir('/path/to/directory');
    foreach($dir as $file)
{
    $ext = pathinfo($file,PATHINFO_EXTENSION);
    if($ext!='jpg') continue;

    $a = explode('-',$file); //grab the end of the string after the -
    $newfilename = end($a); //if there is no dash just take the whole string

    $newlocation = './ch/ch-'.str_replace(array('C','_A'),'', basename($newfilename,'.jpg')).'fs.jpg';
    echo "@copy($file, $newlocation)\n";

}
#and you are done :)

爆炸:基本上将blah-2.jpg这样的文件名转换为array('blah','2.jpg);,然后取end()获取最后一个元素。它几乎与array_pop();

相同

工作示例

这是我的想法代码http://ideone.com/gLSxA