2
<span class="itemopener">82 top</span>&nbsp;<span class="allopener">all</span>

How can I change above to:

<span class="itemopener">top</span>&nbsp;<span class="allopener">82</span>

with PHP on an html file that contains around 30 of those HTML snippets.

Note: 82 can be any integer above 1.

Also, I want to run this script from a new file that I place in a directory, which will run the search and replace once for each of the 8000 HTML files in that directory (the script mustn't timeout before done - perhaps some feedback.)

Adrian33
  • 281
  • 5
  • 16

2 Answers2

2

i wrote function for replacement of the row:

 function replace($row){
    $replaced = preg_replace_callback("~(\<span class=\"itemopener\"\>)(\d{1,5})\s(top\</span\>.*\<span class=\"allopener\"\>).{3}(\</span\>)~iU", function($matches){
    $str = $matches[1] . $matches[3] . $matches[2] . $matches[4];
    return $str;
    }, $row);
    return $replaced;
 }

$s = '<span class="itemopener">82 top</span>&nbsp;<span class="allopener">all</span>';
$replaced = replace($s);

echo "<pre>" . print_r($replaced, 1) . "</pre>";
exit();

Working demo of the function

If you would take file by one row, and do some simple check whether there is those spans you want to replace, then you can send them into this function.. But with number of files you specified, it will take some time.

For scanning of all files in path you can use my answer there: scandir After little editing you can modify it to read only .htm files, and return to you what structure you desire..

Then you take all scanned htm files and process them with something like this:

$allScannedFiles = array("......");
foreach($allScannedFiles as $key => $path){
    $file = file_get_contents($path);
    $lines = explode(PHP_EOL, $file);
    $modifiedFile = "";
    foreach($lines as $line){
        if(strpos($line, "span") && strpos($line, "itemopener")){
             $line = replace($line);
        }
        $modifiedFile .= $line . PHP_EOL;
    }
    file_put_contents($path, $modifiedFile);
}

I wrote this one snippet from the head, so some testing is needed.. Then run it, go make yourself coffe and wait :) If it will timeout, you can increase php timeout. How to do that is asked&answered here: how to increase timeout in php

alternatively you can try load files as DOMDocument and do replacements on that class documentation of DomDocument But if in the files somewhere is not valid html, it may cause you problems..

Community
  • 1
  • 1
Jimmmy
  • 579
  • 12
  • 26
1

I'm using the function created by @Jimmmy (replaced range d{2} by d{1,5} because "Note: 82 can be any integer above 1") and added the files search (tested it and works great) :

<?php

function replace($row){
    $replaced = preg_replace_callback("~(\<span class=\"itemopener\"\>)(\d{1,5})\s(top\</span\>.*\<span class=\"allopener\"\>).{3}(\</span\>)~iU", function($matches){
        $str = $matches[1] . $matches[3] . $matches[2] . $matches[4];
        return $str;
    }, $row);
    return $replaced;
}

foreach ( glob( "*.html" ) as $file )         // GET ALL HTML FILES IN DIRECTORY.
{ $lines = file( $file );                     // GET WHOLE FILE AS ARRAY OF STRINGS.
  for ( $i = 0; $i < count( $lines ); $i++ )  // CHECK ALL LINES IN ARRAY.
    $lines[ $i ] = replace( $lines[ $i ] );   // REPLACE PATTERN IF FOUND.
  file_put_contents( $file,$lines );          // SAVE ALL ARRAY IN FILE.
}
?>