I'm stuck. Ignore the top line, no use for date yet, but will be using in a bit. Having issues primarily with this line:
if(strpos($line, $extension) !== false and (preg_match('#\d#',$line !== false))){
I'm trying to do is that if a domain name ($line) is a .com and has no numbers then echo it. All of the preg_replace and strlen seems to be working, but I can't get it to only perform the way I need. I need to put the preg_match outside of the <=40 rule as it may be causing confusion?
<?php
date_default_timezone_set('UTC');
$extension = '.com';
$lines = file('PoolDeletingDomainsList.txt');
echo "<b>4 Letter premiums for ". date("n/j/Y") .":</b><br />";
foreach($lines as $line)
if(strlen($line)<=40) {
{
// Check if the line contains the string we're looking for, and print if it does
if(strpos($line, $extension) !== false and (preg_match('#\d#',$line !== false))){
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
echo $line;
}
}
}
?>
Return Values
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
Manual preg_match
if(strpos($line, $extension) !== false and (preg_match('#\d#',$line) !== false))){
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
echo $line;
}
replace with
if ((false !== strpos($line, $extension)) && (1 === preg_match('#\d#',$line))){
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
echo $line;
}
This will check if $line contains .com and has numbers (otherwise those preg_replace would have nothing to work with).
Here is what seemed to work for me.
date_default_timezone_set('UTC');
$extension = '.com';
$lines = file('PoolDeletingDomainsList.txt');
echo "<b>4 Letter premiums for ". date("n/j/Y") .":</b><br />";
foreach($lines as $line)
if(strlen($line)<=36) {
{
// Check if the line contains the string we're looking for, and print if it does
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
if ((false !== strpos($line, $extension)) && (0 === preg_match('#\d#',$line)) && (0 === preg_match('/-/', $line))){
echo $line;
}
}
}
?>
According to the preg_match documentation:
preg_match() returns 1 if the pattern matches given subject, 0`` if it does not, or FALSE if an error occurred.
So, according to your current condition, the if statement will evaluate to TRUE if preg_match returns any value that's not FALSE (which includes 1 and 0). And preg_match returns 1 if a match is found, so all your domains will pass the condition and echoed.
To fix the error, change your if statement to:
if(strpos($line, $extension) !== false && !preg_match('#\d#',$line)) {
So you're searching for .com domains that have no numbers in it ("premium domains").
<?php
$lines = array(
'example.com',
'exa13mple.com',
'domain.org',
'google.com',
'37signals.com'
);
foreach ($lines as $line)
{
$matches = array();
$isComDomain = preg_match('/\w+\\.com/', $line, $matches);
$hasNoNumbers = !empty($matches) ? preg_match('/^[a-zA-Z]+\\.com$/', $matches[0]) : false;
if ($isComDomain && $hasNoNumbers) {
print $matches[0] . "\n";
}
}
The isComDomain is a boolean telling if it found a [word characters].com from the line. And if it found, it stores the found domain name in $matches[0].
Then the hasNoNumbers is a boolean telling if the .com domain name contained only chars from a-z and A-Z. You may wish to include "-" in the regex if you allow dashes.
Related
I have to get a output of a list that only contain ports like :8080, not any other ports so the php has to check if the website contains any lines with :8080 port, and if so you will have to print the whole line.
$url = "https://proxymagic.cc/Home/FreeProxies?accesskey=key";
$str = file_get_contents($url);
$lines = explode('
', $str);
foreach($lines as $line) {
if (stripos($line, '8080') !== false) {
$line = $output;
}
echo $output;
}
I'm not sure why you are storing the line if you just want to echo it back out. This will echo each matching line on a separate line.
$url = "https://proxymagic.cc/Home/FreeProxies?accesskey=key";
$str = file_get_contents($url);
$lines = explode('
', $str);
foreach($lines as $line) {
if (stripos($line, '8080') !== false) {
echo $line . "\n<br/>";
}
}
Use file() instead of file_get_contents().
Use array_filter, as Jon Gauthier demonstrates in his answer to a related question:
array_filter($array, function($el) use ($search_text) {
return ( strpos($el['text'], $search_text) !== false );
});
Summary:
$url = "https://proxymagic.cc/Home/FreeProxies?accesskey=key";
$lines = file($url);
$needle = ':8080';
$lines = array_filter($lines, function($line) use ($needle) {
return false !== strpos($line, $needle);
});
print_r($lines);
first time resorting to actually posting on SO.
Also sorry if this has been asked many times, i think ive about read most of them here, but still no dice.
I have a generated log file continaing text i wish to extract the line in the log file is this:
{22:30:47} System:"Obambivas" StarPos:(-59.938,7.375,56.813)ly Body:13 RelPos:(-0.529636,-0.130899,0.838064)km NormalFlight
So far ive manaaged to get the matches via preg_match_all, and works fine.
However i really need each System:"" only once as the log may have several exacly the same.
Ive tried to use array_unique, but im fairly sure im using it wrong as it either retruns nothing or the same results, ie 10+ matches for each match found
So i need just each unique match from the matches found in the log file.
My code so far (sorry if its messy)
And thanks in advance
if (is_dir($log) && is_readable($log)) {
if (!$files = scandir($log, SCANDIR_SORT_DESCENDING)) {
}
$newest_file = $files[0];
if (!$line = file($log . "/" . $newest_file)) {
} else {
foreach ($line as $line_num => $line) {
$pos = strpos($line, 'System:"');
$pos2 = strrpos($line, "ProvingGround");
if ($pos !== false && $pos2 === false) {
preg_match_all("/\System:\"(.*?)\"/", $line, $matches);
$cssystemname = $matches[1][0];
$curSys["name"] = $cssystemname;
preg_match_all("/\StarPos:\((.*?)\)/", $line, $matches2);
$curSys["coordinates"] = $matches2[1][0];
$coord_parts = explode(",", $curSys["coordinates"]);
$curSys["x"] = $coord_parts[0];
$curSys["y"] = $coord_parts[1];
$curSys["z"] = $coord_parts[2];
echo $curSys["name"].' | Coords: '.$curSys["x"].','.$curSys["y"].','.$curSys["z"].'<br />';
}
}
}
}
I added $hash array to avoid duplicates
if (is_dir($log) && is_readable($log)) {
if (!$files = scandir($log, SCANDIR_SORT_DESCENDING)) {
}
$newest_file = $files[0];
if (!$line = file($log . "/" . $newest_file)) {
} else {
$hash = array();
foreach ($line as $line_num => $line) {
$pos = strpos($line, 'System:"');
$pos2 = strrpos($line, "ProvingGround");
if ($pos !== false && $pos2 === false) {
preg_match_all("/\System:\"(.*?)\"/", $line, $matches);
$cssystemname = $matches[1][0];
if ($hash[$cssystemname] == "")
{
$curSys["name"] = $cssystemname;
preg_match_all("/\StarPos:\((.*?)\)/", $line, $matches2);
$curSys["coordinates"] = $matches2[1][0];
$coord_parts = explode(",", $curSys["coordinates"]);
$curSys["x"] = $coord_parts[0];
$curSys["y"] = $coord_parts[1];
$curSys["z"] = $coord_parts[2];
echo $curSys["name"].' | Coords: '.$curSys["x"].','.$curSys["y"].','.$curSys["z"].'<br />';
}
} else $hash[$cssystemname] = "inhash";
}
}
I have a problem where I need to search a HTML page/snippet and replace any value that is between four percentile symbols and convert to a constant variable, e.g. %%THIS_CONSTANT%% becomes THIS_CONSTANT.
Right now I am searching through the page, line by line, and I am able to find matches and replace them by using preg_match_all and preg_replace.
$file_scan = fopen($directory.$file, "r");
if ($file_scan) {
while (($line = fgets($file_scan)) !== false) {
if(preg_match_all('/\%%(.*?)\%%/', $line, $matches)){
foreach($matches as $match){
foreach($match as $m){
$repair = preg_replace('/\%%(.*?)\%%/', $m, $m);
if(preg_match('/\%%(.*?)\%%/', $m, $m)){
} else {
echo $repair.' '.$j;
$j++;
}
}
$lines[$i] = preg_replace('/\%%(.*?)\%%/', constant($repair), $line);
}
} else {
$lines[$i] = $line;
}
$i++;
}
$template[$name] = implode("", $lines);
fclose($file_scan);
}
What this code is not able to do is find and replace multiple matches on a single line. For instance, if there is a line with:
<img src="%%LOGO_IMAGE%%"><h1>%%TITLE%%</h1>
The above code would replace both items with the same value (TITLE). It would also give the error couldn't find constant on the first loop, but work correctly on the second.
This happens very rarely, but I just wish to know how to modify multiple instances on a single line just to be safe.
Edit:
I am able to replace the majority of the code with this:
$file_scan = fopen($directory.$file, "r");
if ($file_scan) {
while (($line = fgets($file_scan)) !== false) {
$line = preg_replace('/\%%(.*?)\%%/', '$2'.'$1', $line);
echo $line;
}
fclose($file_scan);
My last issue is changing the replaced items to constants. Is that possible?
Final Edit:
With the help from Peter Bowers suggestion, I used preg_replace_callback to add the ability to change the keyword to a constant:
foreach($filenames as $file){
$name = str_replace('.html', '', $file);
$template[$name] = preg_replace_callback('/\%%(.*?)\%%/', function($matches){
$matches[0] = preg_replace('/\%%(.*?)\%%/', '$1', $matches[0]);
return constant($matches[0]);
}, file_get_contents($directory.$file));
}
return $template;
Here's a much simpler implementation.
$file_scan = fopen($directory.$file, "r");
if ($file_scan) {
$out = '';
while (($line = fgets($file_scan)) !== false) {
$out .= preg_replace('/\%%(.*?)\%%/', '$1', $line);
$i++;
}
$template[$name] = $out;
fclose($file_scan);
}
Or, even simpler:
$str = file_get_contents($directory.$file);
$template[$name] = preg_replace('/\%%(.*?)\%%/', '$1', $str);
And, since we're going totally simple here...
$template[$name] = preg_replace('/\%%(.*?)\%%/', '$1', file_get_contents($directory.$file));
(Obviously you are losing some of your error checking capabilities as we approach the one-liner, but - hey - I was having fun... :-)
Try with this:
<?php
define('TITLE', 'Title');
define('LOGO_IMAGE', 'Image');
$lines = array();
$file_scan = fopen($directory.$file, "r");
if ($file_scan) {
while (($line = fgets($file_scan)) !== false) {
if(preg_match_all('/\%%(.*?)\%%/', $line, $matches)){
for($i = 0; $i < count($matches[0]); $i++) {
$line = str_replace($matches[0][$i], constant($matches[1][$i]), $line);
}
$lines[] = $line;
print_r($line);
}
}
}
$template[$name] = implode("", $lines);
fclose($file_scan);
?>
I have an application which needs to open the file, then find string in it, and print a line number where is string found.
For example, file example.txt contains few hashes:
APLF2J51 1a79a4d60de6718e8e5b326e338ae533 EEQJE2YX
66b375b08fc869632935c9e6a9c7f8da O87IGF8R
c458fb5edb84c54f4dc42804622aa0c5 APLF2J51 B7TSW1ZE
1e9eea56686511e9052e6578b56ae018 EEQJE2YX
affb23b07576b88d1e9fea50719fb3b7
So, I want to PHP search for "1e9eea56686511e9052e6578b56ae018" and print out its line number, in this case 4.
Please note that there are will not be multiple hashes in file.
I found a few codes over Internet, but none seem to work.
I tried this one:
<?PHP
$string = "1e9eea56686511e9052e6578b56ae018";
$data = file_get_contents("example.txt");
$data = explode("\n", $data);
for ($line = 0; $line < count($data); $line++) {
if (strpos($data[$line], $string) >= 0) {
die("String $string found at line number: $line");
}
}
?>
It just says that string is found at line 0.... Which is not correct....
Final application is much more complex than that...
After it founds line number, it should replace string which something else, and save changes to file, then goes further processing....
Thanks in advance :)
An ultra-basic solution could be:
$search = "1e9eea56686511e9052e6578b56ae018";
$lines = file('example.txt');
$line_number = false;
while (list($key, $line) = each($lines) and !$line_number) {
$line_number = (strpos($line, $search) !== FALSE) ? $key + 1 : $line_number;
}
echo $line_number;
A memory-saver version, for larger files:
$search = "1e9eea56686511e9052e6578b56ae018";
$line_number = false;
if ($handle = fopen("example.txt", "r")) {
$count = 0;
while (($line = fgets($handle, 4096)) !== FALSE and !$line_number) {
$count++;
$line_number = (strpos($line, $search) !== FALSE) ? $count : $line_number;
}
fclose($handle);
}
echo $line_number;
function get_line_from_hashes($file, $find){
$file_content = file_get_contents($file);
$lines = explode("\n", $file_content);
foreach($lines as $num => $line){
$pos = strpos($line, $find);
if($pos !== false)
return $num + 1
}
return false
}
get_line_from_hashes("arquivo.txt", "asdsadas2e3xe3ceQ#E"); //return some number or false case not found.
If you need fast and universal solution that working also for finding line number of multiline text in file, use this:
$file_content = file_get_contents('example.txt');
$content_before_string = strstr($file_content, $string, true);
if (false !== $content_before_string) {
$line = count(explode(PHP_EOL, $content_before_string));
die("String $string found at line number: $line");
}
FYI Works only with PHP 5.3.0+.
$pattern = '/1e9eea56686511e9052e6578b56ae018/';
if (preg_match($pattern, $content, $matches, PREG_OFFSET_CAPTURE)) {
//PREG_OFFSET_CAPTURE will add offset of the found string to the array of matches
//now get a substring of the offset length and explode it by \n
$lineNumber = count(explode("\n", substr($content, 0, $matches[0][1])));
}
If the file is not extremely large then just read the file into an array file, search for the word preg_grep, get the index key for that line and add 1 since the array starts at 0:
$string = "1e9eea56686511e9052e6578b56ae018";
echo key(preg_grep("/$string/", file("example.txt"))) + 1;
I found this to work great and be very efficient; Simply explode the file by each line and search through the array for your search terms like so:
function getLineNum($haystack, $needle){
# Our Count
$c = 1;
# Turn our file contents/haystack into an array
$hsarr = explode("\n", $haystack);
# Iterate through each value in the array as $str
foreach($hsarr as $str){
# If the current line contains our needle/hash we are looking for it
# returns the current count.
if(strstr($str, $needle)) return $c;
# If not, Keep adding one for every new line.
$c++;
}
# If nothing is found
if($c >= count($hsarr)) return 'No hash found!';
}
EDIT: Looking through the other answers, I realize that Guilherme Soares had a similar approach but used strpos, which in this case doesnt work. So I made a few alterations with his idea in mind here:
function getLineNum($haystack, $needle){
$hsarr = explode(PHP_EOL, $haystack);
foreach($hsarr as $num => $str) if(strstr($str, $needle)) return $num + 1;
return 'No hash found!';
}
Live Demo: https://ideone.com/J4ftV3
I wanna read some text files in a folder line by line. for example of 1 txt :
Fast and Effective Text Mining Using Linear-time Document Clustering
Bjornar Larsen WORD2 Chinatsu Aone
SRA International AK, Inc.
4300 Fair Lakes Cow-l Fairfax, VA 22033
{bjornar-larsen, WORD1
I wanna remove line that does not contain of words = word, word2, word3, and does not end with dot .
so. from the example, the result will be :
Bjornar Larsen WORD2 Chinatsu Aone
SRA International, Inc.
{bjornar-larsen, WORD1
I am confused, hw to remove the line? it that possible? or can we replace them with a space?
here's the code :
$url = glob($savePath.'*.txt');
foreach ($url as $file => $files) {
$handle = fopen($files, "r") or die ('can not open file');
$ori_content= file_get_contents($files);
foreach(preg_split("/((\r?\n)|(\r\n?))/", $ori_content) as $buffer){
$pos1 = stripos($buffer, $word1);
$pos2 = stripos($buffer, $word2);
$pos3 = stripos($buffer, $word3);
$last = $str[strlen($buffer)-1];//read the las character
if (true !== $pos1 OR true !== $pos2 OR true !==$pos3 && $last != '.'){
//how to remove
}
}
}
please help me, thank you so much :)
You're using a !== true comparison to test the return-value of the stripos. !== true means "is not absolutely equal-to the boolean value true". The return-value of stripos is numeric, unless the word doesn't exist, in which case it's false. In other words, your condition is always false.
Try updating it to use === false instead. Also, you're using OR in between each; Your example shows that it needs to only contain 1 of them - so if you're checking that "none of them were found", you'll need to use && for everything:
if (($pos1 === false) && ($pos2 === false) && ($pos3 === false) && ($last != '.'))
Regarding "how to remove the line", you'll need to keep a list of all lines you want to keep. This means, we'll actually want to flip the condition above to use !== false and an || between everything (because we want to keep all lines that match any rule).
Try something like this:
$url = glob($savePath.'*.txt');
foreach ($url as $file => $files) {
$handle = fopen($files, "r") or die ('can not open file');
$ori_content= file_get_contents($files);
$linesToKeep = array(); // list of all lines that match our rules
foreach(preg_split("/((\r?\n)|(\r\n?))/", $ori_content) as $buffer){
$pos1 = stripos($buffer, $word1);
$pos2 = stripos($buffer, $word2);
$pos3 = stripos($buffer, $word3);
$last = $str[strlen($buffer)-1];
if (($pos1 !== false) || ($pos2 !== false) || ($pos3 !== false) || ($last == '.')) {
$linesToKeep[] = $buffer; // save this line
}
}
// process list of lines for this file;
// file_put_contents($files, join("\r\n", $linesToKeep)); // write back to file
// $lines = join("\r\n", $linesToKeep); // convert to string to manipulate
}
Now, you'll have every line that matches your ruleset in the $linesToKeep array. You can convert this back to a string with $lines = join("\r\n", $linesToKeep);, or iterate through it and process it however you'd like.
Nice approach... But you can use arrays to read in your file and put it your file. Till now it is fine.
PS: There can be better ways to do...
$url = glob($savePath.'*.txt');
foreach ($url as $file => $files) {
$handle = fopen($files, "r") or die ('can not open file');
$ori_content= file_get_contents($files);
# Declare a variable array to store the contents.
$fileContents = array();
foreach(preg_split("/((\r?\n)|(\r\n?))/", $ori_content) as $buffer){
$pos1 = stripos($buffer, $word1);
$pos2 = stripos($buffer, $word2);
$pos3 = stripos($buffer, $word3);
$last = $str[strlen($buffer)-1];//read the las character
if (($pos1 !== false) || ($pos2 !== false) || ($pos3 !== false) || ($last == '.')){
$fileContents[] = $buffer;
}
}
# Put the contents
file_put_contents($file, implode(PHP_EOL, $fileContents);
}
Try
$url = glob($savePath.'*.txt');
foreach ($url as $file => $files) {
$lines = file($files);
foreach ($lines as $key=>$line) {
if (!preg_match('/(word|word2|word3)/i', $line) && substr($line, -1) != '.') {
unset($lines[$key]);
}
}
$ori_content = implode("\n", $lines);
}
I would just use explode:
$handle = fopen($files, "r") or die ('can not open file');
$ori_content = file_get_contents($files);
$lines = explode ( '\n' , $ori_content );
foreach ( $lines AS $line )
{
if (strpos ( $line , 'word' ) !== false OR strpos ( $line , 'word2' ) !== false OR strpos ( $line , 'word3' ) !== false OR substr ( $line , -1 ) == '.')
{
$newParagraph = $line . '\n';
}
}
echo $newParagraph;
Much simpler than what you were trying to do.
You'll need to create a secondary buffer.
$url = glob($savePath.'*.txt');
foreach ($url as $file => $files) {
$handle = fopen($files, "r") or die ('can not open file');
$ori_content= file_get_contents($files);
/* Create our second buffer */
$buffer2 = "";
foreach(preg_split("/((\r?\n)|(\r\n?))/", $ori_content) as $buffer){
$pos1 = stripos($buffer, $word1);
$pos2 = stripos($buffer, $word2);
$pos3 = stripos($buffer, $word3);
$last = $str[strlen($buffer)-1];//read the last character
/* This will only execute if the three words and a trailing period are _not_ found */
if ($pos1 === false && $pos2 === false && $pos3 === false && $last != '.') {
$buffer2 .= $buffer . PHP_EOL;
}
}
}
echo $buffer2;