I have a text file with data that looks like this:
#dacdcadcasvsa
#svsdvsd
#
#sfcnakjncfkajnc
I want to keep this line
and this one
How can I remove all lines containing # and echo out the lines that don't so it looks like:
I want to keep this line
and this one
All I know is that I have to get_file_contents($filename). Would I have to put it in an array?
Any tips and guidance would be appreciated.
Using file() and foreach()
$lines = file("a.txt");
foreach ( $lines as $line ) {
if ( $line[0] != '#' ){
echo $line;
}
}
Just update the name of the file.
You can replace all the comment lines with empty strings before you output.
<div style="white-space: pre-line;">
<?= preg_replace('/^#.*\n/m', '', file_get_contents($filename)) ?>
</div>
You're thinking along the right lines; although the PHP method (function) you need is actually file_get_contents(), not get_file_contents() (as per your question).
Let's break it down:
We need a way of separating out our data into sortable chunks. As you stated, the best way to do this is using an array.
We could do this, using the hash symbol (#) as a delimiter - but this
would mean the last chunk of text is a mixture of text we want to
remove, and text we want to keep. Instead, we'll be using line
breaks as our delimiter.
Once the data has been separated, we can work on removing those lines that begin with a hash symbol.
Our code will look something like this:
<?php
// Get the file contents
$fileContents = file_get_contents('my_file.txt'); // This could be any file extension
// Split the file by new lines
$contentsArr = preg_split('/\r\n|\r|\n/', $fileContents);
// Function for removing items from an array - https://stackoverflow.com/questions/9993168/remove-item-from-array-if-item-value-contains-searched-string-character?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
function myFilter($string) {
return strpos($string, '?') === false;
}
// Remove comment items from array
$newFileContents = array_filter($fileContents, 'myFilter');
// Concatenate and echo out the result
echo implode(",\n",$newFileContents);
An alternate because I was bored:
foreach(preg_grep('/^#/', file($filename), PREG_GREP_INVERT) as $line) {
echo $line;
}
Read file lines into an array
Get all lines NOT starting with ^ the # character
Loop those lines
So I'm trying to append a string at the end of a row. The row and the string is inputted by the user.
//irrelevant...
$row = $_POST["whichRow"];
$Comment = $_POST["stringValue"];
$lines = array();
$arrayWithComment = array(";", "$actualComment");
$lineCount = 0;
foreach(file('/var/www/html/bkbpNew/tickets.csv') as $line){
if ($lineCount == $row){
array_push($lines, $line, $arrayWithComment[0], $arrayWithComment[1]);}
else{
array_push($lines, $line);}
$lineCount++;
}
file_put_contents('/var/www/html/bkbpNew/tickets.csv', $lines);
And that sort of works, but not in the way that I want it to. Here is the edited file before/after & the desired state:
(Input values for this example are comment = "test" and row = 2)
Desired result of edited file:
1;example;example;example;example;example;example
2;example;example;example;example;example;example;test
3;example;example;example;example;example;example
Edited file BEFORE the above code is executed:
1;example;example;example;example;example;example
2;example;example;example;example;example;example
3;example;example;example;example;example;example
Edited file AFTER the above code is executed:
1;example;example;example;example;example;example
2;example;example;example;example;example;example
;test3;example;example;example;example;example;example
it automatically goes into the next line (Desired result) but I don't want it to. How do I go about this? Cheers!
when you use file(), newline characters are included at the end of the line, so when you're adding your new comment to the end of the line you're adding it after the new line character
I'm not a big fan of your approach to this, but as a quick and dirty solution use the FILE_IGNORE_NEW_LINES flag for file(), and then manually re-add the newline characters for each line in your loop
I have the following strings:
Falchion-Case
P90-ASH-WOOD-WELL-WORN
I also have the following URLS which are inside a text file:
http://csgo.steamanalyst.com/id/115714004/FALCHION-CASE-KEY-
http://csgo.steamanalyst.com/id/115716486/FALCHION-CASE-
http://csgo.steamanalyst.com/id/2018/P90-ASH-WOOD-WELL-WORN
I'm looping through each line in the text file and checking if the string is found inside the URL:
// Read from file
if (stristr($item, "stattrak") === FALSE) {
$lines = file(public_path().'/csgoanalyst.txt');
foreach ($lines as $line) {
// Check if the line contains the string we're looking for, and print if it does
if(preg_match('/(?<!\-)('.$item.')\b/',$line) != false) { // case insensitive
echo $line;
break;
}
}
}
This works perfectly when $item = P90-ASH-WOOD-WELL-WORN however when $item = Falchion-Case It matches on both URL's when only the second: http://csgo.steamanalyst.com/id/115716486/FALCHION-CASE- is valid
Try modifying your regx to match the end of the line, assuming the line ends
'/('.$item.')$/'
This would match
http://csgo.steamanalyst.com/id/115714004/FALCHION-CASE-KEY- <<end of line
Basically do an ends with type match, you can do this too
'/('.$item.')\-?$/'
to optionally match an ending hyphen
You can also use a negative lookahead to negate that unwanted case:
preg_match('/(?<!-)'. preg_quote($item) .'(?!-\w)/i', $line);
when I explode csv file on delimiter (;)
the explode successfully in some excel program and failed in others
also when I explode csv file on delimiter (,)
the explode successfully in some excel program and failed in others
How can I do explode in all versions of excel?
How can I know the perfect delimiter to explode?
yes there is code..
if (!function_exists('create_csv')) {
function create_csv($query, &$filename = false, $old_csv = false) {
if(!$filename) $filename = "data_export_".date("Y-m-d").".csv";
$ci = &get_instance();
$ci->load->helper('download');
$ci->load->dbutil();
$delimiter = ";";
$newline = "\r\n";
$csv = "Data:".date("Y-m-d").$newline;
if($old_csv)
$csv .= $old_csv;
else
$csv .= $ci->dbutil->csv_from_result($query, $delimiter, $newline);
$columns = explode($newline, $csv);
$titles = explode($delimiter, $columns[1]);
$new_titles = array();
foreach ($titles as $item) {
array_push($new_titles, lang(trim($item,'"')));
}
$columns[1] = implode($delimiter, $new_titles);
$csv = implode($newline, $columns);
return $csv;
}
}
sometimes I put $delimiter = ";";
and sometims $delimiter = ",";
thanks..
You can use helper function to detect best delimiter like:
public function find_delimiter($csv)
{
$delimiters = array(',', '.', ';');
$bestDelimiter = false;
$count = 0;
foreach ($delimiters as $delimiter)
if (substr_count($csv, $delimiter) > $count) {
$count = substr_count($csv, $delimiter);
$bestDelimiter = $delimiter;
}
return $bestDelimiter;
}
If you have an idea of the expected data (number of columns) then this might work as a good guess, and could be a good alternative to comparing which occurs the most (depending on what kind of data you're expecting).
It would work even better if you have a header record, I'd imagine. (You could put in a check for specific header values)
Sorry for not fitting it into your code, but I am not really sure what those calls you are making do, but you should be able to fit it around.
$expected_num_of_columns = 10;
$delimiter = "";
foreach (array(",", ";") as $test_delimiter) {
$fid = fopen ($filename, "r");
$csv_row = fgetcsv($fid, 0, $test_delimiter);
if (count($csv_row) == $expected_num_of_columns) {
$delimiter = $test_delimiter;
break;
}
fclose($fid);
}
if (empty($delimiter)) {
die ("Input file did not contain the correct number of fields (" . $expected_num_of_columns . ")");
}
Don't use this if, for example, all or most of the fields contain non-integer numbers (e.g. a list of monetary amounts) and has no header record, because files separated by ; are most likely to use , as the decimal point and there could be the same number of commas and semi-colons.
The short answer is, you probably can't unless you can apply some heuristic to determine the file format. If you don't know and can't detect the format of the file you're parsing, then parsing it is going to be difficult.
However, once you have determined (or, required a particular one) the delimiter format. You will probably find that php's built-in fgetcsv will be easier and more accurate than a manual explode based strategy.
There is no way to be 100% sure you are targeting the real delimiter. All you can do is guessing.
You should start by finding the right delimiter, then explode the CSV on this delimiter.
To find the delimiter, basically, you want a function that counts the number of , and the number of ; and that returns the greater.
Something like :
$array = explode(find_delimiter($csv), $csv);
Hope it helps ;)
Edit : Your find_delimiter function could be something like :
function find_delimiter($csv)
{
$arrDelimiters = array(',', '.', ';');
$arrResults = array();
foreach ($arrDelimiters as $delimiter)
{
$arrResults[$delimiter] = count(explode($delimiter, $csv));
}
$arrResults = rsort($arrResults);
return (array_keys($arrResults)[0]);
}
Well, it looks like you exactly know that your delimiter will be "," or ";". This is a good place to start. Thus, you may try to replace all commas (,) to semicolons (;), and then explode by the semicolon only. However, in this approach you would definitely have a problem in some cases, because some lines of your CSV files could be like this:
"name,value",other name,other value,last name;last value
In this way delimiter of your CSV file will be comma if there will be four columns in your CSV file. However, by changing commas to semicolons you would get five columns which would be incorrect. So, changing some delimiter to another is not a good way.
But still, if your CSV file is correctly formatted, then you may find correct delimiter in any of the lines. So, you may try to create some function like find_delimiter($csvLine) as proposed by #johnkork, but the problem with this is that the function itself can't know which delimiter to search for. However, you exactly know all the possible delimiters, so you may try to create another, quite similar, function like delimiter_exists($csvLine, $delimiter) which returns true or false.
But even the function delimiter_exists($csvLine, $delimiter) is not enough. Why? Because for the instance of CSV line provided above you would get that both "," and ";" are delimiters that exists. For comma it would CSV file with four columns, and for semicolon it would be two columns.
Thus, there is no universal way which would get you exactly what you want. However, there may be another way you can check for - the first line of CSV file which is the header assuming your CSV files have a header. Mostly, headers in CSV file have (not necessarily) no other symbols, except for the alphanumeric names of the columns, which are delimited by the specific delimiter. So, you may try to create function like delimiter_exists($csvHeader, $delimiter) whose implementation could be like this:
function delimiter_exists($csvHeader, $delimiter) {
return (bool)preg_match("/$delimiter/", $csvHeader);
}
For you specific case you may use it like this:
$csvHeader = "abc;def";
$delimiter = delimiter_exists($csvHeader, ',') ? ',' : ';';
Hope this helps!
I have following data in text file
375020222511963
284970411563422
290245594366931
I need to retrieve a random variable from the above text file.
I use the following php code to do that
<?php
$file = file("file.txt");
$len = count($file);
$rand = rand ( 0, $len-1 );
echo $file[$rand];
?>
But it's returning new line along with the retrieved data. I need to retrieve data without new line.
The file() function has an optional second argument taking a bit mask of flags which affect what is returned in the array.
Available flags are FILE_USE_INCLUDE_PATH, FILE_IGNORE_NEW_LINES, and SKIP_EMPTY_LINES. The FILE_IGNORE_NEW_LINES is the one that you want to use in order to have each line in the array not include the trailing newline character.
So, your line of code should look like the following.
$file = file("file.txt", FILE_IGNORE_NEW_LINES);
Descriptions and more info, see http://php.net/file.
Change last line to:
echo trim($file[$rand]);
trim() removes white-spaces (blanks, new lines, tabs) from the beginning and end of a string.
In order to avoid empty lines... If the last line is always the only empty one:
$rand = rand (0, $len - 2); // Instead of -1
Else, if you can have empty lines everywhere, replace the last two lines of code with:
do {
$rand = rand (0, $len - 1);
} while (trim($file[$rand]) == '');
echo $file[$rand];