Find/Replace part of text in PHP and convert to HTML - php

I have a large number of ASCII text files and am listing out the contents of each using the code below:
<?php
$file = $_GET['file'];
$orig = file_get_contents($file);
$a =htmlentities($orig);
echo $a;
?>
Some strings of text in each ASCII file are references to file names of other files and I'm trying to find and replace them with a Hyperlink to that file.
For example, a text file might be called "LAB_E143.txt" which looks like this:
LAB_E143:
LDX $#FF ; load X with $FF
JSR LAB_E151 ; jump to this location
and what I'm trying to find & replace are references beginning with "LAB_" (e.g. LAB_E151 in the example above) so that it displays the text as a Hyperlink with a href of:
http:\\capture.php?file=lab_e151.txt
Clicking on that link will then display the contents of that particular text file and so on. All the references begin with "LAB_" followed by 4 variable characters.
I've tried str_replace but am struggling to parse the 4 variable characters each time.
Any help / pointers greatly appreciated

You should use Regex for such cases. As shudder mentioned, preg_replace_callback should be the best function to use for this purpose.
Detect all references with the following Regex: /LAB_(?<id>\S{4})/
Write a function to replace the matches with the <a> tag
That's it.
$text = 'LAB_8435 Lorem ipsum dolor sit amet. LAB_8337 Amet.';
$formattedText = preg_replace_callback('/LAB_(?<id>\S{4})/', function ($matches) {
return ''.$matches[0].'';
}, $text);
echo $formattedText;

Warning: you want to display file from specific folder - make sure that user can't change the path with provided string (file whitelist, filename sanitization), because it would be possible to do some serious damage.
I suggest not giving a clue that link is directly connected with included file name. Instead /capture.php?file=lab_e151.txt you may have /capture.php?id=e151 and then something like this:
$id = isset($_GET['id']) ? $_GET['id'] : ''; //in php7: $id = $_GET['id'] ?? '';
if (!preg_match('/[0-9A-Za-z]{4}/', $id)) { die('Invalid link'); }
$file = 'lab_' . $id . '.txt';
//...
$convertToLink = function ($matches) {
return '' . $matches[0] . '';
};
$code = preg_replace_callback('/LAB_([0-9A-Za-z]{4})/', $convertToLink, $string);
echo '<pre>' . $code . '</pre>';
If those 4 chars are hex number then you may use this pattern instead: /LAB_([0-9A-Fa-f]{4})/

Related

How to replace PHP code in a file having newlinse

I got some files to change by clicking a button. To go for it, i have the old string to replace, saved in database, and also the new one.
On the click button, it executes a function that is gonna find the old string in the PHP file, then gonna replace it by the new one. (Final goal is to automate the PHP edits in a web software after an update).
My problem is that it perfectly works on short strings (without newline), but as soon as there is a newline into the file, nothing happens.
This is my actual code :
$path = '/mypath/' . $item['path'];
$old_code = $item['old_code'];
$new_code = $item['new_code'];
}
$pos = strpos(file_get_contents($path), $old_code);
$file = file_get_contents($path);
$str = str_replace($old_code, $new_code, $file);
file_put_contents($path, $str);
$pos is "true" if my $old_code doesn't have any newline.
I tried to use preg_match to remove \n, but the problem is that when i'll have to push my edits on the file with file_put_contents, every newline will also disapear.
Example of non-working str_replace :
echo "ok"; echo 'hey there is some spaces before'
echo 'this is a sentence';
$menu = ['test1', 'test200'];
print_r($menu);
$url = "/link/to/test";
$div = "echo \"<div class='central_container' align='center'>\";";
Do you have any idea for resolving this ?
Thanks
if I`m not wrong str_replace() work only with single lines . Its have 2 options.
Option line replace str_replace() with preg_replace() or just use https://regex101.com/ there also have code generator after you finish you Regex

Replacing Relative Links with External Links in PHP String

I am working with an editor that works purely with internal relative links for files which is great for 99% of what I use it for.
However, I am also using it to insert links to files within an email body and relative links don't cut the mustard.
Instead of modifying the editor, I would like to search the string from the editor and replace the relative links with external links as shown below
Replace
files/something.pdf
With
https://www.someurl.com/files/something.pdf
I have come up with the following but I am wondering if there is a better / more efficient way to do it with PHP
<?php
$string = 'A link, some other text, A different link';
preg_match_all('/<a[^>]+href=([\'"])(?<href>.+?)\1[^>]*>/i', $string, $result);
if (!empty($result)) {
// Found a link.
$baseUrl = 'https://www.someurl.com';
$newUrls = array();
$newString = '';
foreach($result['href'] as $url) {
$newUrls[] = $baseUrl . '/' . $url;
}
$newString = str_replace($result['href'], $newUrls, $string);
echo $newString;
}
?>
Many thanks
Lee
You can simply use preg_replace to replace all the occurrences of files starting URLs inside double quotes:
$string = 'A link, some other text, A different link';
$string = preg_replace('/"(files.*?)"/', '"https://www.someurl.com/$1"', $string);
The result would be:
A link, some other text, A different link
You really should use DOMdocument for such job, but if you want to use a regex, this one does the job:
$string = '<a some_attribute href="files/something.pdf" class="abc">A link</a>, some other text, <a class="def" href="files/somethingelse.pdf" attr="xyz">A different link</a>';
$baseUrl = 'https://www.someurl.com';
$newString = preg_replace('/(<a[^>]+href=([\'"]))(.+?)\2/i', "$1$baseUrl/$3$2", $string);
echo $newString,"\n";
Output:
<a some_attribute href="https://www.someurl.comfiles/something.pdf" class="abc">A link</a>, some other text, <a class="def" href="https://www.someurl.com/files/somethingelse.pdf" attr="xyz">A different link</a>

Conversion of text within delimeters to valid url

I have to convert an old website to a CMS and one of the challenges I have is at present there are over 900 folders that contain up to 9 text files in each folder. I need to combine the up to 9 text files into one and then use that file as the import into the CMS.
The file concatenation and import are working perfectly.
The challenge that I have is parsing some of the text in the text file.
The text file contains a url in the form of
Some text [http://xxxxx.com|About something] some more text
I am converting this with this code
if (substr ($line1, 0, 7) !=="Replace") {
$pattern = '/\\[/';
$pattern2 = '/\\]/';
$pattern3 = '/\\|/';
$replacement = '<a href="';
$replacement3 = '">';
$replacement2='</a><br>';
$subject = $line1;
$i=preg_replace($pattern, $replacement, $subject, -1 );
$i=preg_replace($pattern3, $replacement3, $i, -1 );
$i=preg_replace($pattern2, $replacement2, $i, -1 );
$line .= '<div class="'.$folders[$x].'">'.$i.'</div>' ;
}
It may not be the most efficient code but it works and as this is a one off exercise execution time etc is not an issue.
Now to the problem that I cannot seem to code around. Some of the urls in the text files are in this format
Some text [http://xxxx.com] some more text
The pattern matching that I have above finds pattern and pattern2 but as there is no pattern3 the url is malformed in the output.
Regular expressions are not my forte is there a way to modify what I have above or is there another way to get the correctly formatted url in my output or will I need to parse the output a second time looking for the malformed url and correct it before writing it to the output file?
You can use preg_replace_callback() to achieve this:
Find any string of the format [...]
Try to split them by the delimiter | using explode()
If the split array contains two pieces, then it means the [...] string contains two pieces: the link href and the link anchor text
If not, then it means the the [...] string contains only the link href part
Format and return the link
Code:
$input = <<<EOD
Some text [http://xxxxx.com|About something] some more text
Some text [http://xxxx.com] some more text
EOD;
$output = preg_replace_callback('#\[([^\]]+)\]#', function($m)
{
$parts = explode('|', $m[1]);
if (count($parts) == 2)
{
return sprintf('%s', $parts[0], $parts[1]);
}
else
{
return sprintf('%1$s', $m[1]);
}
}, $input);
echo $output;
Output:
Some text About something some more text
Some text http://xxxx.com some more text
Live demo

extract info from another web page

I have this test.php where i have this info :
callername1 : 'Fernando Verdasco1'
callername2 : 'Fernando Verdasco2'
callername3 : 'Fernando Verdasco3'
callername4 : 'Fernando Verdasco4'
callername5 : 'Fernando Verdasco5'
this page automatically changes that name every 10 min
In this another page test1.php
I need a php code that takes only the name of the callername3 and echo'it
Fernando Verdasco3
I've tried this like so test1.php?id=callername3
<?php
$Text=file_get_contents("test.php");
if(isset($_GET["id"])){
$id = $_GET["id"];
parse_str($Text,$data);
echo $data[$id];
} else {
echo "";
}
?>
but no result.
Is there any other option?
If i have "=" instade of ":"
callername1 = 'Fernando Verdasco1'
callername2 = 'Fernando Verdasco2'
callername3 = 'Fernando Verdasco3'
callername4 = 'Fernando Verdasco4'
callername5 = 'Fernando Verdasco5'
And i use This php Code it works
<?php
$Text=file_get_contents("test.php")
;preg_match_all('/callername3=\'([^\']+)\'/',$Text,$Match);
$fid=$Match[1][0];
echo $fid;
?>
i need this to work with ":"
Help?
You should store data in a file with the .php extension, since it's not executable PHP. I looks like you're going for the JSON syntax.
Since you need it to work with ':' I assume, for whatever reason, you can't change the format. Your example with '=' works because of the regexp:
preg_match_all('/callername3=\'([^\']+)\'/',$Text,$Match);
This says, match text like callername3= followed by a ' followed by one or more chars that are not a ' followed by a final '. Everything between the 's is stored in $Match[1][0] (if there were more parts in brackets they be stored in $Match[2][0], etc).
Your example doesn't work since it doesn't account for the spaces before and after the = sign. But we can fix that up and change it to work for : like this:
preg_match('/callername3\s*:\s*\'([^\']+)\'/',$Text,$Match);
echo $Match[1] ."\n";
This displays:
Fernando Verdasco3
And what that regular expression is match text that start callername3 followed by any amount of whitespace (that's the \s*) followed by a :, followed by any amount of whitespace, followed by a name in quotes (that is stored in $Match[1], this is the area of the regular expression enclosed in parenthesis).
I've also used just preg_match because it looks like you only need to match one example.
There is a rather simple approach to tihs:
$fData = file_get_contents("test.php");
$lines = explode("\n", $fData);
foreach($lines as $line) {
$t = explode(":", $line);
echo trim($t[1]); // This will give you the name
}

PHP Explode and Get_Url: Not Showing up the URL

its a little bit hard to understand.
in the header.php i have this code:
<?
$ID = $link;
$url = downloadLink($ID);
?>
I get the ID with this Variable $link --> 12345678
and with $url i get the full link from the functions.php
in the functions.php i have this snippet
function downloadlink ($d_id)
{
$res = #get_url ('' . 'http://www.example.com/' . $d_id . '/go.html');
$re = explode ('<iframe', $res);
$re = explode ('src="', $re[1]);
$re = explode ('"', $re[1]);
$url = $re[0];
return $url;
}
and normally it prints the url out.. but, i cant understand the code..
It's written in kind of a strange way, but basically what downloadLink() does is this:
Download the HTML from http://www.example.com/<ID>/go.html
Take the HTML, and split it at every point where the string <iframe occurs.
Now take everything that came after the first <iframe in the HTML, and split it at every point where the string src=" appears.
Now take everything after the first src=" and split it at every point where " appears.
Return whatever was before the first ".
So it's a pretty poor way of doing it, but effectively it looks for the first occurence of this in the HTML code:
<iframe src="<something>"
And returns the <something>.
Edit: a different method, as requested in comment:
There's not really any particular "right" way to do it, but a fairly straightforward way would be to change it to this:
function downloadlink ($d_id)
{
$html = #get_url ('' . 'http://www.example.com/' . $d_id . '/go.html');
preg_match('/\<iframe src="(.+?)"/', $html, $matches);
return $matches[1];
}

Categories