Reduce whole text to some words in PHP - php

I have a problem. I need a "text reducer".
What i mean: I wrote to text area any words, for example: John Doe is good boy; Then i press some button, and it will get something like:
John Doe
So, it will only output defined worlds, like John Doe, or milk or something like that
Thanks for your help

If you know a black list of words you want to strip out, you could use the array replace function: str_replace:
http://php.net/manual/en/function.str-replace.php
like this:
$blacklist = ['ugly', 'bad', 'censored'];
$yourString = str_replace($yourString, $blacklist, '');
This will remove every word in your blacklist, from your input string.
If you need a whitelist based filter, you could use split your string into an array of words, and then use the array_filter function:
http://php.net/manual/en/function.preg-split.php
http://php.net/manual/en/function.array-filter.php
using something similar to:
$whitelist = ['good', 'neat', 'stuff'];
$tokens = preg_split("/[\s,]+/", $yourString);
$filtered = array_filter($tokens, function ($item) {
return in_array($token, $whitelist);
});
$finalString = implode(' ', $filtered);

Yes you can write a function in this case it receives an array as parameter, but if is static, you could save it on the function.
Also, this could work using a regex with preg_match, but i'll leave that for you.
Currently ignores case thanks to `strtolower', if you don't want to ignore the case, remove this function calls.
function printWhiteListedText($arrWhitelist, $str){
$auxStr = "";
foreach($arrWhitelist as $word){
if(strpos(strtolower($str), strtolower($word)) > -1){
$auxStr .= $word . ' ';
}
}
return trim($auxStr);
}
echo printWhiteListedText(['Hello', 'world'], 'hello this world is great');

Related

PHP match and replace whole word

Hi I am replacing certain names with different value . Here is values I am replacing "#size-name" and "#size" .But the problem is my code replacing only size first and note name for example
#size = "replaceword"
#size-name = "replaceword2"
But its replacing
#size ="replaceword"
#size-name = "replaceword2-name"
How can I replace whole word not part of it here is my code
$tempOutQuery = preg_replace("/(\b($key)\b)/i" , $value , $tempOutQuery);
$tempOutQuery= str_replace("#".$key ,$value ,$tempOutQuery);
both codes are not working
My Full Code
$val= "Hi I want #size dress which is #size-name";
$tempOutQuery = preg_replace("/(\b(size)\b)/i" ,"replaceword", $tempOutQuery);
$tempOutQuery = preg_replace("/(\b(size-name)\b)/i" ,"replaceword2", $tempOutQuery);
If you could make replace without using regulat expressions, then I would suggest using standart str_replace() with arrays:
$val= "Hi i want #size dress which is #size-name";
$search = array('size-name', 'size');
$replace = array('replaceword2', 'replaceword');
$result = str_replace($search, $replace, $val);
The order of search and replace Strings is important!
You should take care that you replace long search-strings first, and the short strings later.
Here's another option for you, using preg_replace_callback. It's actually very similar to Gennadiy's method. The only real difference is that it's using the preg aspect of PHP (and it's a lot more work). But it's another way to skin the proverbial cat.
<?php
// SET OUR DEFAULT STRING
$string = 'Hi I want #size suit which is #size-name';
// LOOK FOR EITHER size-name OR size AND IF YOU FIND IT ...
// RUN THE FUNCTION 'replace_sizes'
$string = preg_replace_callback('~#(size-name|size)~', 'replace_sizes', $string);
// PRINT OUT OUR MODIFIED STRING
print $string;
// THIS IS THE FUNCTION THAT WILL BE RUN EVERY TIME A MATCH IS FOUND
// EITHER 'size' OR 'size-name' WILL BE STORED IN $m[1]
function replace_sizes($m) {
// SET UP AN ARRAY THAT HAS OUR POTENTIAL MATCHES AS KEYS
// AND THE TEXT WE WANT TO REPLACE WITH AS THE VALUE
$size_text_array = array('size-name' => 'replaceword2', 'size' => 'replaceword');
// RETURN WHATEVER THE VALUE IS BASED ON THE KEY
return $size_text_array[$m[1]];
}
This will print out:
Hi I want replaceword suit which is replaceword2
Here is a working demo:
http://ideone.com/njNTbB
You can try pre_replace() to replace whole word from an item of an array in PHP a shown below.
<?PHP
function removePrepositions($text){
$propositions=array('/\bfor\b/i','/\band\b/i');
if( count($propositions) > 0 ) {
foreach($propositions as $exceptionPhrase) {
$text = preg_replace($exceptionPhrase, '', trim($text));
}
$retval = trim($text);
}
return $retval;
}
?>
See the entire post here

PHP Spintax Processor

I've been using the recurisve SpinTax processor as seen here, and it works just fine for smaller strings. However, it begins to run out of memory when the string goes beyond 20KB, and it's becoming a problem.
If I have a string like this:
{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Austin}!
and I want to have random combinations of the words put together, and not use the technique as seen in the link above (recursing through the string until there are no more words in curly-braces), how should I do it?
I was thinking about something like this:
$array = explode(' ', $string);
foreach ($array as $k=>$v) {
if ($v[0] == '{') {
$n_array = explode('|', $v);
$array[$k] = str_replace(array('{', '}'), '', $n_array[array_rand($n_array)]);
}
}
echo implode(' ', $array);
But it falls apart when there are spaces in-between the options for the spintax. RegEx seems to be the solution here, but I have no idea how to implement it and have much more efficient performance.
Thanks!
You could create a function that uses a callback within to determine which variant of the many potentials will be created and returned:
// Pass in the string you'd for which you'd like a random output
function random ($str) {
// Returns random values found between { this | and }
return preg_replace_callback("/{(.*?)}/", function ($match) {
// Splits 'foo|bar' strings into an array
$words = explode("|", $match[1]);
// Grabs a random array entry and returns it
return $words[array_rand($words)];
// The input string, which you provide when calling this func
}, $str);
}
random("{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Austin}!");
random("{This|That} is so {awesome|crazy|stupid}!");
random("{StackOverflow|StackExchange} solves all of my {problems|issues}.");
You can use preg_replace_callback() to specify a replacement function.
$str = "{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Austin}!";
$replacement = function ($matches) {
$array = explode("|", $matches[1]);
return $array[array_rand($array)];
};
$str = preg_replace_callback("/\{([^}]+)\}/", $replacement, $str);
var_dump($str);

Preg match question

I'm sure someone already asked this question, but after searching for more than 1 hour on google, I decided to ask my question here.
I want to itterate over an array excisting of different strings/texts.
These texts contain strings with both ##valuetoreplace## and #valuetoreplace#
I want to make to preg_matches:
$pattern = '/^#{1}+(\w+)+#{1}$/';
if(preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE))
{
// do something with the #values#
}
AND
$pattern = '/^#{2}+(\w+)+#{2}$/';
if(preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE))
{
//do something with the ##value##
}
This works great.
Now my only problem is as follows:
When i have a string like
$valueToMatch = 'proceding text #value#';
My preg_match cant find my value anymore (as i used a ^ and a $).
Question: how can i find the #value# and the ##value##, without having to worry if these words are in the middle of a (multi-line) value?
*In addition:
What i want is to find patterns and replace the #value# with a db value and a ##value## with a array value.
For example:
$thingsToReplace = 'Hello #firstname# #lastname#,
How nice you joined ##namewebsite##.';
should be
'Hello John Doe,
How nice you joined example.com.'
Try this: /##([^#]+)##/ and /#([^#]+)#/, in that order.
Maybe nice to know for other visitors how i did it:
foreach($personalizeThis as $key => $value)
{
//Replace ##values##
$patternIniData = '/#{2}+(\w+)#{2}/';
$return = 'website'; //testdata
$replacedIniData[$key] = preg_replace($patternIniData, $return, $value);
//Replace #values#
$pattern = '/#{1}+(\w+)#{1}/';
$return = 'ASD'; //testdata
$replacedDbData[$key] = preg_replace($pattern, $return, $replacedIniData[$key]);
}
return $replacedDbData;

Replace names in text with links

I want to replace names in a text with a link to there profile.
$text = "text with names in it (John) and Jacob.";
$namesArray("John", "John Plummer", "Jacob", etc...);
$LinksArray("<a href='/john_plom'>%s</a>", "<a href='/john_plom'>%s</a>", "<a href='/jacob_d'>%s</a>", etc..);
//%s shout stay the the same as the input of the $text.
But if necessary a can change de array.
I now use 2 arrays in use str_replace. like this $text = str_replace($namesArray, $linksArray, $text);
but the replace shout work for name with a "dot" or ")" or any thing like that on the end or beginning. How can i get the replace to work on text like this.
The output shout be "text with names in it (<a.....>John</a>) and <a ....>Jacob</a>."
Here is an example for a single name, you would need to repeat this for every element in your array:
$name = "Jacob";
$url = "<a href='/jacob/'>$1</a>";
$text = preg_replace("/\b(".preg_quote($name, "/").")\b/", $url, $text);
Try something like
$name = 'John';
$new_string = preg_replace('/[^ \t]?'.$name.'[^ \t]/', $link, $old_string);
PHP's preg_replace accepts mixed pattern and subject, in other words, you can provide an array of patterns like this and an array of replacements.
Done, and no regex:
$text = "text with names in it (John) and Jacob.";
$name_link = array("John" => "<a href='/john_plom'>",
"Jacob" => "<a href='/jacob'>");
foreach ($name_link as $name => $link) {
$tmp = explode($name, $text);
if (count($tmp) > 1) {
$newtext = array($tmp[0], $link, $name, "</a>",$tmp[1]);
$text = implode($newtext);
}
}
echo $text;
The links will never change for each given input, so I'm not sure whether I understood your question. But I have tested this and it works for the given string. To extend it just add more entries to the $name_link array.
Look for regular expressions. Something like preg_replace().
preg_replace('/\((' . implode('|', $names) . ')\)/', 'link_to_$1', $text);
Note that this solution takes the array of names, not just one name.

extracting multiple fields from a text file using php

what is the best way of extracting multiple (~40 values) from a text file using php?
the data is more or less like:
NAMEA valuea
NAMEB valueb
I'm looking for a proper* approach to extracting this data into a data-structure, because i will need to specify regexs for all of them (all 40).
did i make myself clear?
*meaning, the default/painful method would be for me to do:
$namea = extractfunction("regexa", $textfilevalue);
$nameb = extractfunction("regeb", $textfilevalue);
... 40 times!
The lines may not be in the same order, or be present in each file. Every NAMEA is text like: "Registration Number:", or "Applicant Name:" (ie, with spaces in what i was calling as NAMEA)
Response to the Col.
i'm looking for a sensible "way" of writing my code, so its readable, modifiable, builds an object/array thats easily callable, etc... "good coding style!" :)
#Adam - They do actually... and contain slashes as well...
#Alix - Freaking marvelous man! THat was GOOD! would you also happen to have any insights on how I can "truncate" the rsultant array by removing everything from "key_x" and beyond? Should i open that as a new question?
Here is my take at it:
somefile.txt:
NAMEA valuea
NAMEB valueb
PHP Code:
$file = file_get_contents('./somefile.txt');
$string = preg_replace('~^(.+?)\s+(.+?)$~m', '$1=$2', $file);
$string = str_replace(array("\r\n", "\r", "\n"), '&', $string);
$result = array();
parse_str($string, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
Output:
Array
(
[NAMEA] => valuea
[NAMEB] => valueb
)
You may also be able to further simplify this by using str_getcsv() on PHP 5.3+.
EDIT: My previous version fails for keys that have spaces like #Col. Shrapnel noticed. I didn't read the question with enough attention. A possible solution since you seem to be using keys that always have : appended is this:
$string = preg_replace('~^(.+?):\s+(.+?)$~m', '$1=$2', $file);
To remove everything from key_x to the end of the file you can do something like this:
$string = substr($string, 0, strpos($string, 'key_x'));
So the whole thing would look like this:
somefile.txt:
Registration Number: valuea
Applicant Name: valueb
PHP Code:
$file = file_get_contents('./somefile.txt');
$string = substr($file, 0, strpos($file, 'key_x'));
$string = preg_replace('~^(.+?):\s+(.+?)$~m', '$1=$2', $string);
$string = str_replace(array("\r\n", "\r", "\n"), '&', $string);
$result = array();
parse_str($string, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
Output:
Array
(
[Registration_Number] => valuea
[Applicant_Name] => valueb
)
as far as I get it you can use file() to get an array of strings and then parse these strings with some regexp.
if you add a = sign between names and values, you'll be ble to get the whole thing at once using parse_ini_file()
Assuming your keys (namea, nameb) never have spaces in them:
$contents = file('some_file.txt'); // read file as array
$data = array();
foreach($contents as $line) { // iterate over file
preg_match('/^([^\s]+)\s+(.*)/', $line, $matches); // pull out key and value into $matches
$key = $matches[1];
$value = $matches[2];
$data[$key] = $value; // store key/value pairs in $data array
}
var_dump($data); // what did we get?

Categories