Remove an entire word if it containins a word [duplicate] - php

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Remove entire word if the word contains specific string
How I can remove an entire word that contains a word?
For example, 'releas' should delete released, releases releasing etc.
/* Read in from the file here, not in the function - you only need to read the file once */
$wordlist = array('release','announce');
/* Sample data */
$words = 'adobe releases releases Acrobat X';
foreach ($wordlist as $v)
$words = clean($v,$words);
function clean($wordlist,$value)
{
return preg_replace("/\b$wordlist\b/i", '***',trim($value));
}
echo 'Words: '.$words.PHP_EOL;

You can loop through your $wordlist
function clean($wordlist,$value)
{
foreach ($wordlist as $word) {
$value = preg_replace("/\b\w*$word\w*\b/i", '***', trim($value));
}
return $value;
}
and doing it in one replace
function clean($wordlist,$value)
{
$all_words = implode('|', $wordlist);
return preg_replace("/\b\w*(?:$all_words)\w*\b/i", '***', trim($value));
}
Update:
Looking through other answers and comments, it seems I haven't looked properly at the question. If $wordlist is not an array, you can just use #fthiella's answer.

I would use this REGEXP;
return preg_replace("/\w*$wordlist\w*/i", '***', trim($value));
Applyed to your code, it would be:
foreach ($wordlist as $v)
$words = clean($v, $words);
function clean($word, $value) {
return preg_replace("/\w*$word\w*/i", '***',trim($value));
}
(notice that I renamed $wordlist to $word to make things clearer, since $wordlist is also the name of the array)

try it this way
$_words = implode( '|', $wordlist );
return preg_replace( "/\b\w*{$_words}\w*\b/i", "***", trim( $value ) );
or better
$_words = array();
foreach ( $wordlist as $word ) {
$_words[] = '/\b\w*' . preg_quote( $word ) . '\w*\b/i';
}
return preg_replace( $_words, '***', trim( $value ) );
the second way avoids problems with regex, if some reserved chars appear inside the words.

Related

Converting string with html styling ags to title case

I'm using this function to convert text to title case:
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
// Split the string into separate words
$words = explode(' ', $title);
foreach ($words as $key => $word) {
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array($word, $smallwordsarray))
$words[$key] = ucwords($word);
}
// Join the words back into a string
$newtitle = implode(' ', $words);
return $newtitle;
}
The issue is that if text is bold, italic etc then the function does not work and will not title case the word.
For example: "This is a simple sentence" will be converted to "This is a Simple Sentence". But "This is a simple sentence" will be converted to "This is a simple Sentence".
Any help greatly appreciated.
If you are talking about HTML tags and you want to save it, you can use this implementation:
<?php
/* Your old string */
$string = "<b>asd</b>";
/* Remove html code */
$old = strip_tags($string);
/* Upper case the first letter */
$new = ucfirst($old);
/* Replace old word to new word in $string */
$real = str_replace($old,$new,$string);
/* Here the new string and the old string */
echo $real." ".$string;
?>
So the solution in your code looks like :
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
// Split the string into separate words
$words = explode(' ', $title);
foreach ($words as $key => $word) {
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array(strip_tags($word), $smallwordsarray)) {
$old = strip_tags($word);
$new = ucfirst($old);
$words[key] = str_replace($old,$new,$word);
}
}
// Join the words back into a string
$newtitle = implode(' ', $words);
return $newtitle;
}
<?php
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
$words = $temp = explode(' ', strip_tags($title));
foreach ($temp as $key => $word) {
if ($key == 0 or !in_array($word, $smallwordsarray)) $temp[$key] = ucwords($word);
}
foreach($words as $index => $word) $title = str_replace($word, $temp[$index], $title);
return $title;
}
var_dump(strtotitle('This is a simple sentence'));
var_dump(strtotitle('This is a <b>simple</b> <i>sentence</i>'));
You could use strip_tags this way:
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
// Remove HTML tags
$titleWithoutTags = strip_tags($title);
// Split the string into separate words
$words = explode(' ', $titleWithoutTags);
foreach ($words as $key => $word) {
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array($word, $smallwordsarray))
$words[$key] = ucwords($word);
}
// Join the words back into a string
$newtitle = implode(' ', $words);
return $newtitle;
}

PHP: Normalize a string

I want to normalize (so canonicalize) a string into the normal form for names:
First letter of the name is uppercase
The difficulty by this is now to follow this rule with second and third name.
My method:
public function namilize($string)
{
$strings = explode(' ', $string);
foreach ($strings as $string) {
$string = ucfirst(strtolower($string));
}
$string = implode(' ', $strings);
return $string;
}
Somehow the
$string = ucfirst(strtolower($string));
fails.
What do I have to correct?
Is there a better way?
Regards
EDIT:
Hi,
thank you all for all the comments and answers.
I found another "modern" method:
public function namilize($string)
{
$string = mb_convert_case($string, MB_CASE_TITLE, mb_detect_encoding($string));
}
When I now would additionally add some regex for Mc and O's than it would be complete :)
public function namilize($name) {
$name = strtolower($name);
$normalized = array();
foreach (preg_split('/([^a-z])/', $name, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $word) {
if (preg_match('/^(mc)(.*)$/', $word, $matches)) {
$word = $matches[1] . ucfirst($matches[2]);
}
$normalized[] = ucfirst($word);
}
return implode('', $normalized);
}
Note that this will work for names like John O'Brian, James McManus, etc. For other names with prefixes like McManus, simply add the prefix to the preg_match(). Obviously, this runs the possibility of false positives, but no method is going to be 100% foolproof.
You have to pass the $string by reference, note the &:
public function namilize($string)
{
$strings = explode(' ', $string);
foreach ($strings as &$string) {
$string = ucfirst(strtolower($string));
}
$string = implode(' ', $strings);
return $string;
}
Or use the function suggested by #thetaiko ucwords($string)
The $string inside the foreach will only store the last iteration (or the last name). This doesn't really matter though because the variable in the foreach is never used for output. The implode just undoes what you did with the explode so you will end up with the exact same output as the input. I changed the variable names to be more descriptive in this example:
function namilize($name_in)
{
$a_names = explode(' ', $name_in); //explode string into array
foreach ($a_names as $name) {
$a_fullname[] = ucfirst(strtolower($name)); //build array of proper case names
}
$string = implode(' ', $a_fullname); //convert array into string
return $string;
}

How to parse PHP code in a PHP array?

I am using this piece of code on a site of mine.
If there is PHP code in the array and if you echo it, it does not run.
There is piece of code;
function spin($var){
$words = explode("{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
echo $word." ";
}
}
}
$text = "example.com is {the best forum|a <? include(\"myfile.php\");?>Forum|a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
The file that needs to be included "myfile.php" will not be included. and the PHP codes will be visible. Why is that? How can I solve this problem?
I believe that you will want to run the include statement through eval(). However note that:
"The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand." (PHP.net)
SOURCE: http://php.net/manual/en/function.eval.php
You might try the following:
<?php
function spin($var)
{
$words = explode("\{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
if ( preg_match( "/\<\? include\(\\\"([A-Za-z\.]+)\\\"\)\;\?\>/", $word ) )
{
$file = preg_replace( "/^.*\<\? include\(\\\"([A-Za-z\.]+)\\\"\)\;\?\>.*\$/", "\$1", $word );
$pre = preg_replace( "/^(.*)\<\? include\(\\\"[A-Za-z\.]+\\\"\)\;\?\>.*\$/", "\$1", $word );
$post = preg_replace( "/^.*\<\? include\(\\\"[A-Za-z\.]+\\\"\)\;\?\>(.*)\$/", "\$1", $word );
echo $pre;
include( $file );
echo $post;
}
}
}
}
$text = "example.com is {the best forum|a <? include(\"myfile.php\");?>Forum|a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
?>
My suggestion is a bit of other way,
function spin($var){
$words = explode("{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
if(str_replace(" ","",$word) == 'thisparam'){
echo 'a';
include("myfile.php");
echo 'Forum';
}else{
echo $word." ";
}
}
}
}
$text = "example.com is {the best forum| thisparam |a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
where thisparam is you variable $test is the parameter to run the if statement.
I place a str_replace infront of $word to replace strings to get exact word.
Well it is just a string of text after all. The echo will just output the text...
I suggest you look to make use of eval http://php.net/manual/en/function.eval.php
I cant really tell why you wish to do this though. Whenever I need to use eval and friends I stop to think "Should I be doing this?"

Check if any array values are present at the end of a string

I am trying to test if a string made up of multiple words and has any values from an array at the end of it. The following is what I have so far. I am stuck on how to check if the string is longer than the array value being tested and that it is present at the end of the string.
$words = trim(preg_replace('/\s+/',' ', $string));
$words = explode(' ', $words);
$words = count($words);
if ($words > 2) {
// Check if $string ends with any of the following
$test_array = array();
$test_array[0] = 'Wizard';
$test_array[1] = 'Wizard?';
$test_array[2] = '/Wizard';
$test_array[4] = '/Wizard?';
// Stuck here
if ($string is longer than $test_array and $test_array is found at the end of the string) {
Do stuff;
}
}
By end of string do you mean the very last word? You could use preg_match
preg_match('~/?Wizard\??$~', $string, $matches);
echo "<pre>".print_r($matches, true)."</pre>";
I think you want something like this:
if (preg_match('/\/?Wizard\??$/', $string)) { // ...
If it has to be an arbitrary array (and not the one containing the 'wizard' strings you provided in your question), you could construct the regex dynamically:
$words = array('wizard', 'test');
foreach ($words as &$word) {
$word = preg_quote($word, '/');
}
$regex = '/(' . implode('|', $words) . ')$/';
if (preg_match($regex, $string)) { // ends with 'wizard' or 'test'
Is this what you want (no guarantee for correctness, couldn't test)?
foreach( $test_array as $testString ) {
$searchLength = strlen( $testString );
$sourceLength = strlen( $string );
if( $sourceLength <= $searchLength && substr( $string, $sourceLength - $searchLength ) == $testString ) {
// ...
}
}
I wonder if some regular expression wouldn't make more sense here.

Uppercase the first character of each word in a string except 'and', 'to', etc

How can I make upper-case the first character of each word in a string accept a couple of words which I don't want to transform them, like - and, to, etc?
For instance, I want this - ucwords('art and design') to output the string below,
'Art and Design'
is it possible to be like - strip_tags($text, '<p><a>') which we allow and in the string?
or I should use something else? please advise!
thanks.
None of these are really UTF8 friendly, so here's one that works flawlessly (so far)
function titleCase($string, $delimiters = array(" ", "-", ".", "'", "O'", "Mc"), $exceptions = array("and", "to", "of", "das", "dos", "I", "II", "III", "IV", "V", "VI"))
{
/*
* Exceptions in lower case are words you don't want converted
* Exceptions all in upper case are any words you don't want converted to title case
* but should be converted to upper case, e.g.:
* king henry viii or king henry Viii should be King Henry VIII
*/
$string = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");
foreach ($delimiters as $dlnr => $delimiter) {
$words = explode($delimiter, $string);
$newwords = array();
foreach ($words as $wordnr => $word) {
if (in_array(mb_strtoupper($word, "UTF-8"), $exceptions)) {
// check exceptions list for any words that should be in upper case
$word = mb_strtoupper($word, "UTF-8");
} elseif (in_array(mb_strtolower($word, "UTF-8"), $exceptions)) {
// check exceptions list for any words that should be in upper case
$word = mb_strtolower($word, "UTF-8");
} elseif (!in_array($word, $exceptions)) {
// convert to uppercase (non-utf8 only)
$word = ucfirst($word);
}
array_push($newwords, $word);
}
$string = join($delimiter, $newwords);
}//foreach
return $string;
}
Usage:
$s = 'SÃO JOÃO DOS SANTOS';
$v = titleCase($s); // 'São João dos Santos'
since we all love regexps, an alternative, that also works with interpunction (unlike the explode(" ",...) solution)
$newString = preg_replace_callback("/[a-zA-Z]+/",'ucfirst_some',$string);
function ucfirst_some($match)
{
$exclude = array('and','not');
if ( in_array(strtolower($match[0]),$exclude) ) return $match[0];
return ucfirst($match[0]);
}
edit added strtolower(), or "Not" would remain "Not".
How about this ?
$string = str_replace(' And ', ' and ', ucwords($string));
You will have to use ucfirst and loop through every word, checking e.g. an array of exceptions for each one.
Something like the following:
$exclude = array('and', 'not');
$words = explode(' ', $string);
foreach($words as $key => $word) {
if(in_array($word, $exclude)) {
continue;
}
$words[$key] = ucfirst($word);
}
$newString = implode(' ', $words);
I know it is a few years after the question, but I was looking for an answer to the insuring proper English in the titles of a CMS I am programming and wrote a light weight function from the ideas on this page so I thought I would share it:
function makeTitle($title){
$str = ucwords($title);
$exclude = 'a,an,the,for,and,nor,but,or,yet,so,such,as,at,around,by,after,along,for,from,of,on,to,with,without';
$excluded = explode(",",$exclude);
foreach($excluded as $noCap){$str = str_replace(ucwords($noCap),strtolower($noCap),$str);}
return ucfirst($str);
}
The excluded list was found at:
http://www.superheronation.com/2011/08/16/words-that-should-not-be-capitalized-in-titles/
USAGE: makeTitle($title);

Categories