Reformat a text file in PHP - php
I want to reformat a text file from this:
• Name - 5 September 12:19
- Message
To this:
Name (5 September, 12:19)
Message
Where the names are in bold text and it may be some indications that steps forward in the messages (-- -- -- --). These indications will be replaces with a <hr>. You can see the whole text file here.
I have came up with this:
$url = 'http://erik-edgren.nu/files/history/apg29/jesus-september-2014.txt';
$lines = file($url, FILE_IGNORE_NEW_LINES);
foreach($lines AS $line) {
$info = explode(' - ', $line);
if(strlen($info[0]) > '• ') {
echo '<b>'.str_replace('• ', '', $info[0]).'</b>';
}
echo !isset($info[1]) ? '' : ' ('.$info[1].')';
echo '<br>';
}
But I don't know how I can reformat the document as I want in the best way possible. Any solution on how I can accomplish this?
This is the basic idea of what I would do. You probably need to replace '•' with unicode for that character. This script does not probably work, but it has the general idea of what I would do.
<?php
$url = 'http://erik-edgren.nu/files/history/apg29/jesus-september-2014.txt';
$thedata=file_get_contents($url);
$lines=explode(PHP_EOL,$thedata);
$line1='';
foreach($lines as $a)
{
if(substr($a,2,2)=='• ')
{
$data=explode(' ',$a);
$line1=$data[1] . ' (' . $data[3] . ' ' . $data[4] . ', ' . $data[5] . ')'.PHP_EOL;
}
if(substr($a,2,2)=='- ')
{
echo $line1 . substr($a,2) . PHP_EOL;
}
}
?>
Related
Unexpected result using OR operator in regular expression
I've a problem with a regular expression. I have a text which is read from a file. The text can contain one or more IDs separated by comma. And then I have a list of IDs and want to check if one of these IDs match with my text so I try to use an OR operator: $idString = '2561,3,261,6,540,33,3105,2085,38,42,1066,49,3377,53,3161,91,356,3179,3695,3184,370,123,3451,124,3710,2188,141,404,1435,160,1443,432,435,440,1721,3261,2498,205,3282,476,482,3301,486,749,3309,243,3059,759,2046,4,262,785,534,541,3360,34,3106,2086,39,43,50,3378,54,1337,61,1351,3157,3162,360,3696,3185,631,3450,3200,666,1436,673,1444,3748,3262,2499,206,3279,3283,470,477,483,3302,490,755,760,2047,2562,1029,263,23,542,35,3107,2087,40,552,553,1321,47,51,3379,55,1338,3163,361,3697,3186,633,3452,639,143,3223,1445,3749,1450,3263,2500,207,3284,478,484,3303,2559,264,1297,22,543,36,44,57,1339,3389,62,3164,3677,362,3180,634,144,1685,1446,430,700,208,3286,479,1249,485,3306,2558,255,265,524,30,288,46,2095,63,2375,3165,403,1447,3242,696,1724,3557,3304,1770,3066,2563,266,544,2338,555,3131,3166,2204,415,1448,1239,3288,480,3305,754,267,545,3370,2378,3152,3170,648,147,679,1449,2537,753,2546,505,2564,3335,268,535,537,539,546,549,65,69,3167,148,3244,744,3068,2565,269,286,547,292,1334,1340,3659,3168,383,153,1705,3267,3060,2566,270,271,3099,548,1660,398,154,1706,2511,746,3332,2568,272,3148,422,3269,752,768,273,3381,3153,3199,155,468,784,274,3093,325,1657,3319,510,3329,3333,275,1432,2230,441,1722,773,3338,276,3641,2108,491,3339,277,2398,107,3181,2245,757,3346,2100,619,1760,2050,3351,2103,667,19,3372,2534,1064,351,1726,2394,2508,2538,2104,3147,2083,2097,2042,2096,2165,2049,2525,2526,1774,2392,2080,2043,2542,2547,2129,2540,2536,2190,2226,2569,2572,2373,2507'; $idString = str_replace(',', '|', $idString); $text = '1453,2018'; if (preg_match('/' . $idString . '/', $text)) { echo 'yes' . PHP_EOL; } else { echo 'no' . PHP_EOL; } I'm expecting that nothing matches because the IDs 1453 and 2018 are not found in my lookup string but it matches. I think that's because the ID 3 matches with 1453 but this is not correct for my use case.
That's too easy to work around it using arrays. You shouldn't use Regular Expressions if you can work with them but it seems this is not your real problem but an MCVE for a different one. You should use word boundaries \b otherwise a number like 4 is found in 1453. preg_match() third argument holds results to analyze what is going on. preg_match('/\b(?:' . $idString . ')\b/', $text, $match)
The syntax for preg_match is ($pattern, $text). Change it as follows, worked for me. <?php $idString = '2561,3,261,6,540,33,3105,2085,38,42,1066,49,3377,53,3161,91,356,3179,3695,3184,370,123,3451,124,3710,2188,141,404,1435,160,1443,432,435,440,1721,3261,2498,205,3282,476,482,3301,486,749,3309,243,3059,759,2046,4,262,785,534,541,3360,34,3106,2086,39,43,50,3378,54,1337,61,1351,3157,3162,360,3696,3185,631,3450,3200,666,1436,673,1444,3748,3262,2499,206,3279,3283,470,477,483,3302,490,755,760,2047,2562,1029,263,23,542,35,3107,2087,40,552,553,1321,47,51,3379,55,1338,3163,361,3697,3186,633,3452,639,143,3223,1445,3749,1450,3263,2500,207,3284,478,484,3303,2559,264,1297,22,543,36,44,57,1339,3389,62,3164,3677,362,3180,634,144,1685,1446,430,700,208,3286,479,1249,485,3306,2558,255,265,524,30,288,46,2095,63,2375,3165,403,1447,3242,696,1724,3557,3304,1770,3066,2563,266,544,2338,555,3131,3166,2204,415,1448,1239,3288,480,3305,754,267,545,3370,2378,3152,3170,648,147,679,1449,2537,753,2546,505,2564,3335,268,535,537,539,546,549,65,69,3167,148,3244,744,3068,2565,269,286,547,292,1334,1340,3659,3168,383,153,1705,3267,3060,2566,270,271,3099,548,1660,398,154,1706,2511,746,3332,2568,272,3148,422,3269,752,768,273,3381,3153,3199,155,468,784,274,3093,325,1657,3319,510,3329,3333,275,1432,2230,441,1722,773,3338,276,3641,2108,491,3339,277,2398,107,3181,2245,757,3346,2100,619,1760,2050,3351,2103,667,19,3372,2534,1064,351,1726,2394,2508,2538,2104,3147,2083,2097,2042,2096,2165,2049,2525,2526,1774,2392,2080,2043,2542,2547,2129,2540,2536,2190,2226,2569,2572,2373,2507'; $idString = str_replace(',', '|', $idString); $text = '1453,2018'; if (preg_match('/(' . $text . ')/', $idString)) { echo 'yes' . PHP_EOL; } else { echo 'no' . PHP_EOL; } ?>
You can see what gets matched by your Regex by outputting the matches, eg: if (preg_match('/' . $idString . '/', $text, $matches)) { echo 'yes' . PHP_EOL; print_r($matches); } else { echo 'no' . PHP_EOL; } You'd have to adapt your regex to match against whole words only... for example like this: if (preg_match('/\b(' . $idString . ')\b/', $text)) { https://regex101.com/r/M1Pieb/2/ Or you could avoid using regex altogether (recommended, its getting a bit crazy..) by using explode $idString = '2561,3,261,6,540,33,3105,2085,38,42,1066,49,3377,53,3161,91,356,3179,3695,3184,370,123,3451,124,3710,2188,141,404,1435,160,1443,432,435,440,1721,3261,2498,205,3282,476,482,3301,486,749,3309,243,3059,759,2046,4,262,785,534,541,3360,34,3106,2086,39,43,50,3378,54,1337,61,1351,3157,3162,360,3696,3185,631,3450,3200,666,1436,673,1444,3748,3262,2499,206,3279,3283,470,477,483,3302,490,755,760,2047,2562,1029,263,23,542,35,3107,2087,40,552,553,1321,47,51,3379,55,1338,3163,361,3697,3186,633,3452,639,143,3223,1445,3749,1450,3263,2500,207,3284,478,484,3303,2559,264,1297,22,543,36,44,57,1339,3389,62,3164,3677,362,3180,634,144,1685,1446,430,700,208,3286,479,1249,485,3306,2558,255,265,524,30,288,46,2095,63,2375,3165,403,1447,3242,696,1724,3557,3304,1770,3066,2563,266,544,2338,555,3131,3166,2204,415,1448,1239,3288,480,3305,754,267,545,3370,2378,3152,3170,648,147,679,1449,2537,753,2546,505,2564,3335,268,535,537,539,546,549,65,69,3167,148,3244,744,3068,2565,269,286,547,292,1334,1340,3659,3168,383,153,1705,3267,3060,2566,270,271,3099,548,1660,398,154,1706,2511,746,3332,2568,272,3148,422,3269,752,768,273,3381,3153,3199,155,468,784,274,3093,325,1657,3319,510,3329,3333,275,1432,2230,441,1722,773,3338,276,3641,2108,491,3339,277,2398,107,3181,2245,757,3346,2100,619,1760,2050,3351,2103,667,19,3372,2534,1064,351,1726,2394,2508,2538,2104,3147,2083,2097,2042,2096,2165,2049,2525,2526,1774,2392,2080,2043,2542,2547,2129,2540,2536,2190,2226,2569,2572,2373,2507'; $idStrings = explode(',', $idString); $values = ['1453', '2018']; $matchedValue = null; foreach ($values as $value) { if (in_array($value, $idStrings)) { $matchedValue = $value; break; } } if ($matchedValue !== null) { echo 'yes: ' . $matchedValue; } else { echo 'no'; }
PHP Search for a keyword (Action ') from a text file, prints all lines with that keyword, then counts how many lines are printed
So I just started learning PHP, and I wanted to search for a certain keyword (Action ') from a text file, then print all the lines with the keyword, then count all the lines printed. Here's what I have so far: <?php $searchfor = 'ERR:'; echo "Lines found with the keyword " . "\"" . $searchfor . "\"" . "\n"; $array = array_filter(array_map(function($v){ return (stripos($v,'Action') !== false)? $v : false; },array_filter(file('sampleTest.log',FILE_SKIP_EMPTY_LINES),function($v) { return (!empty(trim($v))); }))); # This will implode the lines echo (!empty($array))? implode('',$array) : ''; # This will count the array echo "<br><br>Total lines printed: " . ((!empty($array))? count($array) : 0); ?> So basically it looks for a certain keyword, in this case, "ERR:" from a certain text file, then prints all of the lines with "ERR:" and then it counts all the lines printed. So what I wanted to do was look for the keyword (Action '). That's a space after the word Action and a single apostrophe. But it seems like it doesn't read the apostrophe('). It prompts me this error in CMD: ' (T_CONSTANT_ENCAPSED_STRING) in C:\xampp\php\newTest.php on line 11 ' (T_CONSTANT_ENCAPSED_STRING) in C:\xampp\php\newTest.php on line 11
Here is a simplified version of your code. <?php $searchfor = "Action '"; $file = file_get_contents("sampleTest.log"); $matches = array(); echo "Lines found with the keyword " . "\"" . $searchfor . "\"" . "\n"; $lines = explode(PHP_EOL,$file); foreach($lines as $line){ if (strpos($line, $searchfor) !== false){ $matches[] = $line; echo $line."<br>"; } } if(!empty($matches)) echo "<br><br>Total lines printed: ".count($matches); else echo "<br><br> No matches."; ?> The script will read the log file and save each line separately. It then goes through all lines and if the search word is in the line, it prints the line and saves it to the matches array that is counted at the end of the script.
magento full text search not working on Live
Magento full text search not working I do following steps full text search option enable from system->configuration->catalogsearch and app/code/core/Mage/CatalogSearch/Model/resources/Fulltext.php change $likeCond = '(' . join(' OR ', $like) . ')'; to $likeCond = '(' . join(' AND', $like) . ')'; but still i not able to search fulltext word exactly match.
You also need to change $where .= ($where ? ' OR ' : '') . $likeCond; to $where .= ($where ? ' AND ' : '') . $likeCond;
How to do such string manipulations in PHP?
I need to convert "01,02,03,04,05,07:01" to: <b>07</b><b>09</b><b>30</b><b class="color_blue_ball">11</b> That is ,wrap those before : with <b></b> ,but those after : with <b class="color_blue_ball"></b>.If there's no :,all should be wrapped with <b></b> Anyone knows how to do this?
No need for regex: echo '<b>' . str_replace(array(',', ':'), array('</b><b>', '</b><b class="color_blue_ball">'), "01,02,03,04,05,07:01") . '</b>'; Edit: if the "01,02,03,04,05,07:01,04,06" is valid, then the idea the same but explode is added: $parts = explode(':', "01,02,03,04,05,07,01,04:06"); echo '<b>' . str_replace(',', '</b><b>', $parts[0]) . (isset($parts[1]) ? str_replace(',', '</b><b class="color_blue_ball">', ',' . $parts[1]) : '') . '</b>';
A tad more verbose: <?php function wrapValues($array, $wrapper) { $result = array(); foreach ($array as $elem) { $result []= str_replace('?', $elem, $wrapper); } return implode('', $result); } $values = "01,02,03,04,05,07:01,02"; $firstWrapper = '<b>?</b>'; $secondWrapper = '<b class="color_blue_ball">?</b>'; list($first, $second) = explode(':', $values); echo wrapValues(explode(',', $first), $firstWrapper) . wrapValues(explode(',', $second), $secondWrapper);
I don't know if it's the best way to do it, but I would probably split the string on the :, then on ,, and then deal with each part separately and join them back together.
How do I deny some keywords on user input
Example user input that should be denied: House for sale Car for rent WTB iphone with cheap price How do I make my code deny inputs like those above? $title = array('rent','buy','sale','sell','wanted','wtb','wts'); $user_title = stripslashes($_POST['title']); if (in_array($user_title, $title)) { $error = '<p class="error">Do not include ' . $user_title . ' on your title</p>'; }
If you want your denied words to be complete words and not just part of another word for it to be considered denied, you can use a regex based solution with word boundaries: // array of denied words. $deniedWords = array('rent','buy','sale','sell','wanted','wtb','wts'); // run preg_quote on each array element..as it may have a regex meta-char in it. $deniedWords = array_map('preg_quote',$deniedWords); // construct the pattern as /(\bbuy\b|\bsell\b...)/i $pat = '/(\b'.implode('\b|\b',$deniedWords).'\b)/i'; // use preg-match_all to find all matches if(preg_match_all($pat,$user_title,$matches)) { // $matches[1] has all the found word(s), join them with comma and print. $error = 'Do not include ' . implode(',',$matches[1]); } Ideone Link
You can use stripos(): $title = array('rent','buy','sale','sell','wanted','wtb','wts'); $user_title = stripslashes($_POST['title']); foreach($title as $word) { if (stripos($user_title, $word) !== false) { $error = '<p class="error">Do not include ' . $word . ' on your title</p>'; break; } }
You can also use regex: if (preg_match("/(rent|buy|sale|sell|wanted|wtb|wts)/is", $user_title)) { $error = '<p class="error">Do not include ' . $user_title . ' on your title</p>'; }
You can utilize explode() in order to separate the words in $user_title and check each one to ensure it does not exist in $title. $invalidWords = ''; $words = explode(' ', stripslashes($_POST['title'])); foreach($words as $word) { if (in_array($word, $title)) { $invalidWords .= ' ' . $word; } } if (!empty($invalidWords)) { echo '<p class="error">Do not include the following words in your title: ' . $invalidWords . '</p>'; } RegEx is probably best, but off-hand I cannot easily figure out the expression required in order for you to be able to output all of the invalid words in a list to the user.