say i have a file named redirections.txt that looks like this:
www: http://www.example.com/hub/
icloud: http://www.example.com/icloud/
dev: http://www.example.com/development/latest/projects.php
how would i go about processing that text document as domain-prefix: redirect-url? (or "if $_SERVER['HTTP_HOST'] equals domain-prefix.example.com, goto redirect-url")
currently i have:
$file = file('redirections.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($file as $line => $cont){
preg_match('/(*.?): http:\/\/www.example.com\/(*.?)\//', $cont, $matches);
print_r($matches); // Debug. Was trying to see if it worked.
}
You can use explode() to split the line:
$split = explode(': ', $cont);
if (count($split) == 2) {
list ($domain_prefix, $redirect_url) = $split;
if ($_SERVER['HTTP_HOST'] == "$domain_prefix.example.com") {
header("Location: $redirect_url");
exit();
}
}
There might be better ways to achieve want you want, but if you need to use the code already presented, try this:
foreach($file as $line => $cont){
preg_match('/(?P<domain>\w+): http:\/\/www.example.com(?P<path>\/.*)/', $cont, $matches);
print_r($matches); // Debug.
Related
This might be an easy one but not for me.
I have this function:
function pingAddress($ip) {
// Read from file
$lines = file('F:\share\result.txt');
foreach($lines as $line)
{
// Check if the line contains the string we're looking for, and print if it does
if(strpos($line, $ip) !== false)
echo $line;
}
}
The text file looks like this:
192.168.50.104 UP
192.168.50.105 UP
192.168.50.106 DOWN
192.168.50.107 UP
If I give ip 192.168.50.1 for example it returns all the lines from 192.168.50.1 to 192.168.50.199 and I need it to return only that specific line and if possible only what's after ip: UP or DOWN.
Help would be nice :-)
By using strpos(), you are accepting partial matches, which causes 192.168.50.1 to match all your examples.
Instead, split the line on a space, and check for a full IP match. Then you can return the UP or DOWN part.
function pingAddress($ip) {
// Read from file
$lines = file('F:\share\result.txt');
foreach($lines as $line){
$parts = explode(' ', $line);
if($parts[0] == $ip){
return $parts[1];
}
}
}
echo pingAddress('192.168.50.1'); // nothing returned
echo pingAddress('192.168.50.105'); // UP
Just add a "return;" after "echo $line;" The function stops, after the searched string is found.
function pingAddress($ip) {
// Read from file
$lines = file('F:\share\result.txt');
foreach($lines as $line)
{
// Check if the line contains the string we're looking for, and print if it does
if(strpos($line, $ip) !== false)
echo $line;
return;
}
}
You would need to check that there is a space after the IP address to ensure it is the full address and not part of another IP.
I've also changed this so that it reads the file a line at a time, so if it finds the IP address it stops reading there (and returns the UP or DOWN). This saves reading the entire file before searching...
function pingAddress($ip) {
// Add space for search
$ip .= ' ';
$fp = fopen("a.csv", "r");
while ( $line = fgets($fp) )
{
// Check if the line contains the string we're looking for, and print if it does
if(strpos($line, $ip) !== false)
return trim(substr($line, strlen($ip)));
}
fclose($fp);
return '';
}
<span class="itemopener">82 top</span> <span class="allopener">all</span>
How can I change above to:
<span class="itemopener">top</span> <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.)
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> <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..
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.
}
?>
I have a file that contains something like this:
test:fOwimWPu0eSaNR8
test2:vogAqsfXpKzCfGr
I would like to be able to search the file for say test and it set the string after the : to a variable so it can be displayed, used etc.
Here is the code I have so far for finding 'test' in the file.
$file = 'file.txt';
$string = 'test';
$searchFile = file_get_contents($file);
if (preg_match('/\\b'.$string.'\\b/', $searchFile)) {
echo 'true';
// Find String
} else {
echo 'false';
}
How would I go about doing this?
This should work for you:
Just get your file into an array with file() and then simply preg_grep() all lines, which have the search string before the colon.
<?php
$file = "file.txt";
$search = "test";
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$matches = preg_grep("/^" . preg_quote($search, "/") . ":(.*?)$/", $lines);
$matches = array_map(function($v){
return explode(":", $v)[1];
}, $matches);
print_r($matches);
?>
output:
Array ( [0] => fOwimWPu0eSaNR8 )
I have a php program that looks at a log file and prints it to a page (code below). I don't want the user of said website to be able to look at any line containing a /. I know I could use trim to delete certain characters, but is there a way to delete the entire line? For example, I want to keep something like "Hello" and delete something like /xx.xx.xx.xx connected. All the lines I wish to delete have the same common key, /. Peoples names in said log file have <>s around them, so I must use htmlspecialcharacters
$file = file_get_contents('/path/to/log', true);
$file = htmlspecialchars($file);
echo nl2br($file);
Thanks for your help!
EDIT:
Thanks for all of the answers, currently tinkering with them!
EDIT2:
final code:
<?php
$file = file_get_contents('/path/to/log', true);
// Separate by line
$lines = explode(PHP_EOL, $file);
foreach ($lines as $line) {
if (strpos($line, '/') === false) {
$line = htmlspecialchars($line . "\n");
echo nl2br($line);
}
}
?>
Do you mean, like this?
$file = file_get_contents('/path/to/log', true);
// Separate by line
$lines = explode(PHP_EOL, $file);
foreach ($lines as $line) {
if (strpos($line, '/') === false) {
// If the line doesn't contain a "/", echo it
echo $line . PHP_EOL;
}
}
For anyone wondering, PHP_EOL is the PHP constant for "end of line" and promotes consistency between different systems (Windows, UNIX, etc.).
If you are iterating through the file line by line you can check with preg_match if the line contains /character and skip the echo if it does. If not, first split them at new line and iterate over that array.
If you don't want to split the file you can probably use preg_replace with a regexp such as (^|\n).*/.*(\n|$) and replace with empty string.
Use the str_replace function -
http://php.net/manual/en/function.str-replace.php. Alternate solution (before escaping the special characters) -
/* pattern /\/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\sconnected/ = /xx.xx.xx.xx connected */
/* pattern will be replaced with "newtext" */
$file = file_get_contents("/path/to/log", true);
$lines = explode("\n", $file);
foreach ($lines as $line)
$correctline = preg_replace( '/\/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\sconnected/', 'newtext', $line );
echo $correctline;
}
<?php
$file = file_get_contents("/path/to/log", true);
$lines = explode("\n", $file);
foreach ($lines AS $num => $line)
{
if ( strpos($line, "/") === false ) // Line doesn't contain "/"
{
echo htmlspecialchars($line) . "\n";
}
}
?>
Is there such a function in PHP that does grep -f filename in unix/linux systems.
If there is none, what PHP functions/tools would help in creating a customised method/function for this. Thanks!
Actually IMHO, I'd say it's the following:
$result = preg_grep($pattern, file($path));
See preg_grepDocs and fileDocs.
If you need to do that (recursively) over a set of files, there is also glob and foreach or the (Recursive)DirectoryIterator or the GlobIteratorDocs and not to forget the RegexIteratorDocs.
Example with SplFileObject and RegexIterator:
$stream = new SplFileObject($file);
$grepped = new RegexIterator($stream, $pattern);
foreach ($grepped as $line) {
echo $line;
}
Output (all lines of $file containing $pattern):
$grepped = new RegexIterator($stream, $pattern);
foreach ($grepped as $line) {
echo $line;
}
Demo: https://eval.in/208699
You can combine the file_get_contens() function to open a file and the preg_match_all() function to capture contents using a regex.
$file = file_get_contents ('path/to/file.ext');
preg_match_all ('regex_pattern_here', $file, $matches);
print_r ($matches);