Php regular expression echo characters after a string - php

I have a large .txt file, within the .txt file, it contains the numbers 712 and other characters. example (712iu3 89234) or (712jnksuiosd). The characters after 712 will change, they may have spaces. I have a php script that reads the file line by line. I am trying to echo all characters after 712 If there are spaces I'd like to remove the spaces. I only need the first 20 characters excluding the spaces. So far I've tried
$file = new SplFileObject("1.txt");
// Loop until we reach the end of the file.
while (!$file->eof()) {
// Echo one line from the file.
echo $file->fgets();
}
// Unset the file to call __destruct(), closing the file handle.
$file = null;

try using the code below
<?php
$file = new SplFileObject("test.txt");
// Loop until we reach the end of the file.
while (!$file->eof()) {
$newString = str_replace(' ', '', $file->fgets());
if (strpos($newString, '712') !== false) {
$strWith712 = substr($newString, 0, 20);
$post = strripos($strWith712, '712');
$str = substr ($strWith712, $post );
echo $str;
}
}
$file = null;
?>
this replaces the white spaces and then searches for the string with the number '712' if a string is found then the letters after the number are printed
the strripos function is used to check the postiton of the string in a sentence from the last.

Related

How to get preg_replace() to delete text between two tags?

I'm trying to make a function in PHP that can delete code within two tags from all .js file within one folder and all its subfolders. So far everything works except preg_replace(). This is my code:
<?php
deleteRealtimeTester('test');
function deleteRealtimeTester($folder_path)
{
foreach (glob($folder_path . '/*.js') as $file)
{
$string = file_get_contents($file);
$string = preg_replace('#//RealtimeTesterStart(.*?)//RealtimeTesterEnd#', 'test2', $string);
$file_open = fopen($file, 'wb');
fwrite($file_open, $string);
fclose($file_open);
}
$subfolders = array_filter(glob($folder_path . '/*'), 'is_dir');
if (sizeof($subfolders) > 0)
{
for ($i = 0; $i < sizeof($subfolders); $i++)
{
echo $subfolders[$i];
deleteRealtimeTester($subfolders[$i]);
}
}
else
{
return;
}
}
?>
As mentioned I want to delete everything inside these tags and the tags themselve:
//RealtimeTesterStart
//RealtimeTesterEnd
It is important that the tags contains the forward slashes and also that if a file contains multiple of these tags, only code from //RealtimeTesterStart to //RealtimeTesterEnd is deleted and not from //RealtimeTesterEnd to //RealtimeTesterStart.
I hope that someone can help me.
You could also change your regex to use the [\s\S] character set which can be used to match any character, including line breaks.
So have the following
preg_replace('#\/\/RealtimeTesterStart[\s\S]+\/\/RealtimeTesterEnd#', '', $string);
This would remove the contents of //RealtimeTesterStart to //RealtimeTesterEnd and the tags themselves.
I'm assuming that //RealtimeTesterStart, //RealtimeTesterEnd and the code in between are on different lines? In PCRE . does NOT match newlines. You need to use the s modifier ( and you don't need the () unless you need the captured text for the replacement):
#//RealtimeTesterStart.*?//RealtimeTesterEnd#s
Also, look at GLOB_ONLYDIR for glob instead of array_filter. Also, also, maybe file_put_contents instead of fopen etc.
Maybe something like:
foreach (glob($folder_path . '/*.js') as $file) {
$string = file_get_contents($file);
$string = preg_replace('#//RealtimeTesterStart.*?//RealtimeTesterEnd#s', 'test2', $string);
file_put_contents($file, $string);
}
foreach(glob($folder_path . '/*', GLOB_ONLYDIR) as $subfolder) {
deleteRealtimeTester($subfolder);
}

loadHTMLFile fails to return URL

<?php
$url="http://somedomain/something";
$lines = file('text.txt');
foreach ($lines as $line_num => $line) {
echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
$dom = new DOMDocument;
$dom->loadHTMLFile($url.$line); //cannot load this
foreach ($dom->getElementsByTagName('p') as $node) {
// do stuff with $node
echo $node->nodeValue, "\n";
}
}
fclose($handle);
?>
I would like to attach the url to the lines of the text file:
Example
$url.$line1 (http://somedomain/something/line1)
$url.$line2 (http://somedomain/something/line2)
I have succesfully set up everything and the loop works well too. But whenever I try to concatenate the url with the line an HTTP 500 Error is returned
Also these characters '%0D%0A' attch themselves to end of the $url.$line and hence the error?
Any help appreciated
Update: The error is because of the '%0D%0A' characters somehow attaching themselves to the end of each url. Any idea how to remove them?
The extra characters you're getting, %0D%0A, are the carriage return and line feed characters for Windows computers. To get rid of them, you can use file with the FILE_IGNORE_NEW_LINES flag:
$lines = file('text.txt', FILE_IGNORE_NEW_LINES);
This will stop the carriage return characters being including on the end of each line in the array.
Alternatively, you can chomp the line ending with rtrim:
$line = rtrim($line);

Reading text after a certain character in php

Okay so I have a text file and inside of the text file I have these lines:
IP = 127.0.0.1
EXE = Client.exe
PORT = 8080
TITLE = Title
MAINT = False
MAINT-Message = This is the message.
what I am wanted to do is get the 'False' part on the fifth line.
I have the basic concept but I can't seem to make it work. This is what I have tried:
<?php
$file = file_get_contents('LauncherInfo.txt');
$info = explode(' = ', $file);
echo $info[5];
?>
And with this I get a result but when I echo $info[5] it gives me 'False Maint-Message' so it splits it but it only splits at the = sign. I want to be able to make it split at the where I have pressed enter to go onto the next line. Is this possible and how can I do it?
I was thinking it would work if I make it explode on line one and then do the same for the second line with a loop until it came to the end of the file? I don't know how to do this though.
Thanks.
I think you're looking for the file(), which splits a file's contents into an array of the file's lines.
Try this:
$file = file('LauncherInfo.txt');
foreach ($file as $line) {
if ($line) {
$splitLine = explode(' = ',$line);
$data[$splitLine[0]] = $splitLine[1];
}
}
echo $data['MAINT'];
Just in case you were curious, since I wasn't aware of the file() function. You could do it manually like this
<?php
$file = file_get_contents('LauncherInfo.txt');
$lines = explode("\n", $file);
$info=array();
foreach($lines as $line){
$split=explode(' = ',$line);
$info[]=$splitline[1];
}
echo $info[5];//prints False
?>

PHP - Find/Replace Text in RTF/txt files

I'm running into an issue with finding specific text and replacing it with alternative text.
I'm testing my code below with .rtf and .txt files only. I'm also ensuring the files are writable, from within my server.
It's a hit and miss situation, and I'm curious if my code is wrong, or if this is just weirdness of opening and manipulating files.
<?php
$filelocation = '/tmp/demo.txt';
$firstname = 'John';
$lastname = 'Smith';
$output = file_get_contents($filelocation);
$output = str_replace('[[FIRSTNAME]]', $firstname, $output);
$output = str_replace('[[LASTNAME]]', $lastname, $output);
$output = str_replace('[[TODAY]]', date('F j, Y'), $output);
// rewrite file
file_put_contents($filelocation, $output);
?>
So, inside the demo.txt file I have about a full page of text with [[FIRSTNAME]], [[LASTNAME]], and [[TODAY]] scattered around.
It's hit and miss with the find/replace. So far, [[TODAY]] is always replaced correctly, while the names aren't.
Has anyone had this same issue?
(on a side note, I've checked error logs and so far no PHP warning/error is returned from opening the file, nor writing it)
Hard to say for sure without seeing the contents of demo.txt. My first guess is that it might be a problem with using brackets for your pointers. I would try changing to something not used by RTF like percent signs or an asterisk. ex: %%FIRSTNAME%%, **FIRSTNAME** (this is assuming of course that you have control of the contents of demo.txt.)
I have had this issue too. It seems like Microsoft Word inserts formatting codes in the tags. I have made a blog post about how to get around this on my technical blog.
http://tech.humlesite.eu/2017/01/13/using-regular-expression-to-merge-database-content-into-rich-text-format-template-documents/
The PHP example is shown here:
<?php
$file = file_get_contents('mergedoc.rtf');
// To temporary get rid of the escape characters...
$mergetext = str_replace("\\", "€€", $file);
// New seven part regex with default value detection
$regex2 = '/<<((?:€€[a-z0-9]*|\}|\{|\s)*)([a-z0-9.\-\+_æøåÆØÅA-Z]*)((?:€€[a-z0-9]*|\}|\{|\s)*)([a-z0-9.\-\+_æøåÆØÅA-Z]*)((?:€€[a-z0-9]*|\}|\{|\s)*)(?:\s*:(.*?)\s*)?((?:€€[a-z0-9]*|\}|\{|\s)*)>>/';
// Find all the matches in it....
preg_match_all($regex2,$mergetext, $out, PREG_SET_ORDER);
// Lets see the result
var_dump($out);
foreach ($out as $match) {
$whole_tag = $match[0]; // The part we actually replace.
$start = $match[1]; // The start formatting that has been injected in our tag, if any
$tag = $match[2]; // The tag word itself.
if (($match[4].$match[6]) != "") { //some sec-part tag or default value?
$end = $match[5]; // The end formatting that might be inserted.
if ($end == "") {
$end = $match[7]; // No end in 5, we try 7.
}
} else {
$end = $match[3]; // No second tag or default value, we find end in match-3
}
$secPartTag = $match[4]; // Do we have inserted some formatting inside the tag word too ?
if ($secPartTag != "") {
$tag .= $secPartTag; // Put it together with the tag word.
}
$default_value = $match[6];
// Simple selection of what we do with the tag.
switch ($tag) {
case 'COMPANY_NAME':
$txt = "MY MERGE COMPANY EXAMPLE LTD";
break;
case 'SOMEOTHERTAG':
$txt = "SOME OTHER TEXT XX";
break;
case 'THISHASDEFAULT':
$txt = "";
break;
default:
$txt = "NOTAG";
}
if ($txt == "") {
$txt = $default_value;
}
// Create RTF Line breaks in text, if any.
$txt = str_replace(chr(10), chr(10)."\\line", $txt);
// Do the replace in the file.
$mergetext = str_replace($whole_tag, $start.$txt.$end, $mergetext);
}
// Put back the escape characters.
$file = str_replace("€€", "\\", $mergetext);
// Save to file. Extention .doc makes it open in Word by default.
file_put_contents("ResultDoc.doc", $file);
?>

Replace a whole line where a particular word is found in a text file

How can I replace a particular line of text in file using php?
I don't know the line number. I want to replace a line containing a particular word.
One approach that you can use on smaller files that can fit into your memory twice:
$data = file('myfile'); // reads an array of lines
function replace_a_line($data) {
if (stristr($data, 'certain word')) {
return "replacement line!\n";
}
return $data;
}
$data = array_map('replace_a_line', $data);
file_put_contents('myfile', $data);
A quick note, PHP > 5.3.0 supports lambda functions so you can remove the named function declaration and shorten the map to:
$data = array_map(function($data) {
return stristr($data,'certain word') ? "replacement line\n" : $data;
}, $data);
You could theoretically make this a single (harder to follow) php statement:
file_put_contents('myfile', implode('',
array_map(function($data) {
return stristr($data,'certain word') ? "replacement line\n" : $data;
}, file('myfile'))
));
Another (less memory intensive) approach that you should use for larger files:
$reading = fopen('myfile', 'r');
$writing = fopen('myfile.tmp', 'w');
$replaced = false;
while (!feof($reading)) {
$line = fgets($reading);
if (stristr($line,'certain word')) {
$line = "replacement line!\n";
$replaced = true;
}
fputs($writing, $line);
}
fclose($reading); fclose($writing);
// might as well not overwrite the file if we didn't replace anything
if ($replaced)
{
rename('myfile.tmp', 'myfile');
} else {
unlink('myfile.tmp');
}
You have to overwrite the entire file.
So, for the relatively small file, read file into array, search for the word, replace found row, write all the rest into file.
For the big file the algorithm is slightly different, but quite the same in general.
Important part is file locking
that's why we prefer a database.
You can also use multi-line mode with regular expressions
preg_match_all('/word}/m', $textfile, $matches);
this is, of course, assuming it's a smaller document at the ready and loaded. Otherwise, the other answers are far more 'real-world' of a solution.
If you don't know the line, you will have to search over all lines.
Either iterate over the file line by line or read the file into memory all at once.
Then either find the word with a combination of strpos and str_replace or
use preg_replace.
If you iterate, simply use strpos and replace the line once it didn't return FALSE. Then save the file back to disk.
$filedata = file('filename');
$newdata = array();
$lookfor = 'replaceme';
$newtext = 'withme';
foreach ($filedata as $filerow) {
if (strstr($filerow, $lookfor) !== false)
$filerow = $newtext;
$newdata[] = $filerow;
}
Now $newdata contains the file contents as an array (use implode() if you don't want array) with the line containing "replaceme" replaced with "withme".
This is good if you are looking for a substring (ID) in a line and want to replace the old line with the new one.
Code:
$id = "123";
$new_line = "123,Programmer\r"; // We're not changing the ID, so ID 123 remains.
$contents = file_get_contents($dir);
$new_contents= "";
if( strpos($contents, $id) !== false) { // if file contains ID
$contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
foreach ($contents_array as &$record) { // for each line
if (strpos($record, $id) !== false) { // if we have found the correct line
$new_contents .= $new_line; // change record to new record
}else{
$new_contents .= $record . "\r";
}
}
file_put_contents($dir, $new_contents); // save the records to the file
echo json_encode("Successfully updated record!");
}
else{
echo json_encode("failed - user ID ". $id ." doesn't exist!");
}
Example:
Old file:
ID,occupation
123,student
124,brick layer
Running the code will change file to:
New file:
ID,occupation
123,programmer
124,brick layer
You could turn the file into an array using the explode(); function, edit any item in the array, use the implode(); function to turn the array back into a string, then you can put the string back into the file using the file_put_contents(); function. This is shown in the following function :
function file_edit_contents($file_name, $line, $new_value){
$file = explode("\n", rtrim(file_get_contents($file_name)));
$file[$line] = $new_value;
$file = implode("\n", $file);
file_put_contents($file_name, $file);
}
Maybe this could help:
$data = file("data.php");
for($i = 0;$i<count($data);$i++){
echo "<form action='index.php' method='post'>";
echo "<input type='text' value='$data[$i]' name='id[]'><br>";
}
echo "<input type='submit' value='simpan'>";
echo "</form>";
if(isset($_POST['id'])){
file_put_contents('data.php',implode("\n",$_POST['id'])) ;
}
This function should replace a full line in a file:
function replace($line, $file) {
if ( file_get_contents($file) == $line ) {
file_put_contents($file, '');
} else if ( file($file)[0] == $line.PHP_EOL ) {
file_put_contents($file, str_replace($line.PHP_EOL, '', file_get_contents($file)));
} else {
file_put_contents($file, str_replace(PHP_EOL.$line, '', file_get_contents($file)));
}
}
The first if statement (line 2) checks if the line to remove is the only line. It then empties the file. The second if statement (line 4) checks if the line to remove is the first line in the file. If so, it then proceeds to remove that line by using str_replace($line.PHP_EOL, '', file_get_contents($file)). PHP_EOL is a new line, so this will remove the line contents and then the line break. Finally, the else statement will only get called if the line to remove is not the only contents and it's not at the start of the file. It then uses the str_replace, but this time with PHP_EOL.$line and not $line.PHP_EOL. That way, if the line is the very last line of the file, it will remove the line break before it and then delete the line.
Usage:
replace("message", "database.txt");
This removes a line with the contents message from the file database.txt if the line exists. If you wanted to shorten it, you could do something like this:
function replace($line,$file){if(file_get_contents($file)==$line){file_put_contents($file,'');}else if(file($file)[0]==$line.PHP_EOL){file_put_contents($file,str_replace($line.PHP_EOL,'', file_get_contents($file)));}else{file_put_contents($file,str_replace(PHP_EOL.$line,'',file_get_contents($file)));}}
I hope that answers your question :)
If you not going to lock the file while processing it, then
access the file,
modify the line (if found) and stop looking for additional lines to replace,
and re-save it with maximum haste (if found).
That said, it doesn't make sense to sacrifice accuracy for speed. This question states that a word must be matched in the line. For that reason, partial matches must be prevented -- regex offers word boundaries (\b).
$filename = 'test.txt';
$needle = 'word';
$newText = preg_replace(
'/^.*\b' . $needle . '\b.*/mui',
'whole new line',
file_get_contents($filename)
1,
$count
);
if ($count) {
file_put_contents($filename, $newText);
}
The pattern:
/ #starting pattern delimiter
^ #match start of a line (see m flag)
.* #match zero or more of any non-newline character
\b #match zero-width position separating word character and non-word character
word #match literal string "word"
\b #match zero-width position separating word character and non-word character
.* #match zero or more of any non-newline character to end of line
/ #ending pattern delimiter
m #flag tells ^ character to match the start of any line in the text
u #flag tells regex engine to read text in multibyte modr
i #flag tells regex engine to match letters insensitively
If using case-insensitive searching but you need the actual matched word in the replacement string, write parentheses around the needle in the pattern, then use $1 in your replacement string.
You can do like this:
$file = file('data.txt');
$data = 'new text';
$some_index = 2;
foreach($file as $index => $line){
if($index == $some_index){
$file[$index] = $data . "\n";
}
}
$content = implode($file);
file_put_contents('data.txt', $content);
I've had similar task and gnarf's answer helped a lot.
But better way to do this is JSON. If you have to change JSON file, you can use this code.
Code just gets existing JSON and applies that to the variable:
$base_data = json_decode(file_get_contents('data.json'), true);
$ret_data = json_encode($base_data , JSON_PRETTY_PRINT);
After this add/modify $ret_data array as you like and put it back to file:
file_put_contents('data.json', $ret_data)
`
$base_data = json_decode(file_get_contents('data.json'), true);
if(!empty($_POST["update_data_file"])){
if(empty($_POST["update_key"]) || empty($_POST['update_value'])){
return_response(false, true, "Update Key or Update Value is missing");
}
if(!is_array($_POST["update_key"])){
return_response(false, false, "Update Key is not an array");
}
if(!is_array($_POST["update_value"])){
return_response(false, false, "Update Key is not an array");
}
$update_keys = $_POST['update_key'];
$update_values = $_POST['update_value'];
$key_length = count($update_keys);
$ret_data = $base_data; // $base_data is JSON from file that you want to update
for($i=0; $i<$key_length; $i++){
$ret_data[$update_keys[$i]] = $update_values[$i];
}
$ret_data = json_encode($ret_data, JSON_PRETTY_PRINT);
if(file_put_contents('data.json', $ret_data)){
return_response(true, false, "Data file updated");
}
return_response(false, false, "Error while updating data file");
}`
`
function return_response($success = true, $reload = false, $msg = ""){
echo json_encode
(
[
"success"=>$success,
"msg"=> $msg,
"reload"=> $reload
]
);
exit;
}`
JQuery part:
`
$("button").click(function(){
let inputs_array = $(this).data("inputs").split(",");
var input_value = "";
var post_input_keys = [];
var post_input_values = [];
for(var i = 0; i < inputs_array.length; i++){
input_value = $("#"+inputs_array[i]).val();
post_input_keys[i] = inputs_array[i];
post_input_values[i] = input_value;
}
send_ajax_data(post_input_keys, post_input_values);
});`
`
function send_ajax_data(update_key = [], update_value = []){
$.ajax({
type : "POST",
url : "path_to_php_file.php",
data : {
update_data_file: 1,
update_key: update_key,
update_value: update_value
},
dataType : 'json',
success : function(data) {
console.log(data.msg);
}
});
}`
HTML:
`
<form id="fill_details_form" class="form" action="" method="post">
<input type="hidden" name="update_data_file" value="1" />
<div class="row mt-3">
<div class="col-sm-3">
<div class="form-group">
<label for="form_name">Logo Width</label>
<input type="text" class="form-control" id="logo_width" name="logo_width" value="" />
<div class="help-block with-errors"></div>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label for="form_name">Logo Height</label>
<input type="text" class="form-control" id="logo_height" name="logo_height" value="" />
<div class="help-block with-errors"></div>
</div>
</div>
<div class="col-sm-3">
<label for="form_name"></label>
<div class="form-group">
<button
type="button"
id="update_logo_dims"
class="btn btn-primary"
data-inputs="logo_width,logo_height"
>
Update logo width and height
</button>
</div>
</div>
</div>
</form>
`
data.json example:
`
{
"logo_file_name": "favicon.png",
"logo_width": "153",
"logo_height": "36",
"logo_url": "https:\/\/google.com?logourl",
"website_url": "https:\/\/google.com",
"website_title": "WEbsite Title",
"favicon_file_name": "favicon.PNG",
}
`

Categories