Here's a simple version of my problem:

<?php
$words = "hEllO wOrLD"; //the input (is usually always different each time)
$phrase = "I made a program which prints Hello World";
$result = str_ireplace("$words", "<b>$words</b>", "$phrase"); //str_ireplace(search_for, replace_with, apply_to)
echo $result;
?>

This would produce the output "I made a program which prints hEllo wOrLD"

What I want to do is that for any value in the variable $words (capital letter or non capital) to not affect the casing of the part of $phrase which is to be bolded. So Ideal output would be "I made a program which prints Hello World"

I'll repeat: The casing (capital or small) of the part which is to be bolded should not change.

Hi,

Not sure if this is what you want. My reading comprehension is off at times, and today is one of those times. It's probably due to long working hours with a minimum pay :).

Codes below should give you the output "I made a program which prints Hello World"

<?php
$words = "hEllO wOrLD"; //the input (is usually always different each time)
$words = ucwords(mb_strtolower($words));
$phrase = "I made a program which prints Hello World";
$result = str_ireplace("$words", "<b>$words</b>", "$phrase"); //str_ireplace(search_for, replace_with, apply_to)
echo $result;
?>
Member Avatar

diafol

$words = "hEllO wOrLD"; //the input (is usually always different each time)
$phrase = "I made a program which prints Hello World";
echo preg_replace("/($words)/i", '<b>${1}</b>', $phrase);

That should do it - Check the time for running both examples to see which is quickest - I have no idea.

I don't think you understood my problem fully veedeoo, but ardav- that solution worked.
Just one extra thing I want it to do is to search and match each word within the input or $phrase individually OR together. I'll explain it better in codee.

E.g. the following code:

<?php
$words = "hEllO wOrLD"; //the input (is usually always different each time)
$phrase = "I made a program which prints hello World and hello world and helloworld and World Helloer";
echo preg_replace("/($words)/i", '<b>${1}</b>', $phrase);
?>

Produces the output: "I made a program which prints hello World and hello world and helloworld and World Helloer"

Whereas I would like it to also match the other (substrings) of the original string, producing the output: "I made a program which prints hello World and hello world and helloworld and World Helloer"

ahaah! That's what I thought yesterday. My head was spinning, but I know for sure somewhere in the back of my head, I did this type of work before. It was one for the adult search functions. It will highlight the most possible matches..exact or from the fragments of words within the string.

kinda like this

<?php
$phrase = "I made a program which prints hello World and hello world and helloworld and World Helloer";
$words = "hEllO wOrLD";
## experimenting with strip_tags as shown ->http://www.w3schools.com/php/func_string_strip_tags.asp
$words = preg_replace('/\s\s+/', ' ', strip_tags(trim($words)));

$more_relevant = ''; ## not sure but may work, 
## $words = explode(' ',$words); ## this don't work codes are tired maybe :)
foreach(explode(' ', $words) as $word)
{
## testing if we can make the first match or more relevant to be red and bold
$first_match = '<b style="color:red;">'.$word.'</b>'; 
## this will be included in the echo which more precise matched
$more_relevant .= $first_match." ";

## matching all occurrences within string, exact or from fragments .
$phrase = str_ireplace($word, $first_match, $phrase);
}
## echo the $phrase in bold red in precise matched, and blue on the matched from fragments.
$phrase = str_ireplace(rtrim($more_relevant), '<b style="color:navy;">'.$words.'</b>', $phrase);

echo $phrase;
?>

I just noticed that if you give the script above a mirrored image strings,. the script will make the matched red :)

$phrase = "I made a program which prints hello World and hello world and helloworld and World Helloer.. Helloer World and helloworld and World hello prints which program  a made I.";
Member Avatar

diafol

Just change the pattern for this:

$pattern = '/([?]*' .  str_replace(" ",'[\s]*',$words) . '[?]*)/i';

Works for me:

THe [?]* allows the an enclosed string to be found.
The [\s]* makes spaces in the words to be optional.

SO:

<?php
$words = "hEllO wOrLD"; //the input (is usually always different each time)
$pattern = '/([?]*' .  str_replace(" ",'[\s]*',$words) . '[?]*)/i';
$phrase = "I made a program helloworld which prints Hello World hello worlder";
$result = preg_replace($pattern, '<b>${1}</b>', $phrase);
echo $result;
?>

Gives:

I made a program helloworld which prints Hello World hello worlder

You could also tie in underscores and dashes too if you like - or make other characters 'optional' like quotes, apostrophes etc

Back to the three liner:

$words = "hEllO wOrLD"; //the input (is usually always different each time)
$phrase = "I made a program helloworld which prints Hello World hello worlder";
echo preg_replace('/([?]*' .  str_replace(" ",'[\s]*',$words) . '[?]*)/i', '<b>${1}</b>', $phrase);

//EDIT
Here's for dashes, underscores etc:

$words = "hEllO wOrLD"; //the input (is usually always different each time)
$array = array(" ","-","_","'");
$words = str_replace($array,"['\s_-]*",$words);
$pattern = '/([?]*' .  $words . '[?]*)/i';
$phrase = "I made a program helloworld which prints Hello World hello worlder";
echo preg_replace($pattern, '<b>${1}</b>', $phrase);
Member Avatar

diafol

Sorry just got an error, str_replace overwriting each time with $array, so changed to this:

$words = "hEllO wOrLD"; //the input (is usually always different each time)
$skipchars = array(" ","-","_","'");
$phrase = "I made a program helloworld which prints Hello World hello worlder";
echo preg_replace('/([?]*' .  str_replace('@@@', "['\s_-]*",str_replace($skipchars,'@@@',$words)) . '[?]*)/i', '<b>${1}</b>', $phrase);

Thank you all very much. The above solution works the best^^

Lastly, I'm trying to match substrings such as "hello" or "world" on its own or commas in between.

<?php
$words = "hEllO wOrLD"; //the input (is usually always different each time)
$skipchars = array(" ","-","_","'", ",");
$phrase = "world hello hello,world"; 
echo preg_replace('/([?]*' .  str_replace('@@@', "['\s_-]*",str_replace($skipchars,'@@@',$words)) . '[?]*)/i', '<b>${1}</b>', $phrase);
?>

As can be seen above I tried to add a comma into the $skipchars array like so

$skipchars = array(" ","-","_","'", ",");

but that didn't work. I have no idea how individual substrings can be matched though.

Member Avatar

diafol

Sorry on holiday for a week so can't help. Anybody?

Member Avatar

diafol

To include commas:

$skipchars = array(" ","-","_","'", ",");

AND

"[\,'\s_-]*"
Member Avatar

diafol

OK asif. I'm playing with OOP at the moment, so thought I'd use your problem with which to experiment. It works for me so far (not tested thoroughly). If any OOP guys out there could tell me where I've really overcooked it/ buggered it up, that would be great too:

class/class.search.php

<?php
class searchMe{
	private $delim;
	private $flag;
	private $rep_pattern;
	private $skipchars;
	private $split_pattern;
	private $output;
	private $s;
	private $c;
	private $search_patterns;
	private $split;
	private $count;
	private $word_boundary;
	private $replacement;
	private $replace_classname;
	
	public function __construct($search,$content,$flag=NULL,$split=NULL,$wb=NULL,$class=NULL){
		//CONFIGS
		$this->s = $search;
		$this->c = $content;
		$this->split = false;			//default = false
		$this->delim = "/";	
		$this->flag = "i";				//default = 'i'
		$this->word_boundary = true;	//default = true
		$this->rep_pattern = "[\,'\s_-]*";
		$this->skipchars = array(" ","-","_","'",",");
		$this->split_pattern = "[,\s_-]+";
		$this->replace_classname = "found1"; //default css hook (.found1)
		
		//DEAL WITH PASSED VARS
		if(!is_null($flag))$this->setFlag($flag);
		if(!is_null($split))$this->setSplit($split);
		if(!is_null($wb))$this->setWB($wb);
		if(!is_null($class))$this->replace_classname = addslashes(htmlentities($class));
		//CREATE IT!
		$this->makePatternArray();
	}
	
	private function addDelim($r){
		$wb = ($this->word_boundary) ? '\b' : '';
		return $this->delim . $wb . "($r)" . $wb.  $this->delim . $this->flag;	
	}
	
	private function makePatternArray(){
		if($this->split){
			$p_array = preg_split($this->delim .$this->split_pattern . $this->delim, $this->s);
			$this->search_patterns = array_map(array($this, 'addDelim'),$p_array);
		}else{
			$this->search_patterns = $this->addDelim('[?]*' .  str_replace('@@@', $this->rep_pattern, str_replace($this->skipchars,'@@@',$this->s)) . '[?]*');
		}
		$this->makeOutput();
	}
	
	private function createReplacement(){
		switch(true){
			case $this->replace_classname == "b" || $this->replace_classname == "strong":
				$this->replacement = '<strong>${1}</strong>';
				break;
			case $this->replace_classname == "i" || $this->replace_classname == "em":
				$this->replacement = '<em>${1}</em>';
				break;
			default:
				$this->replacement = '<span class="'.$this->replace_classname.'">${1}</span>';
				break;
		}
		return $this->replacement;	
	}
	
	private function makeOutput(){
		$this->output = preg_replace($this->search_patterns, $this->createReplacement(), $this->c,-1,$count);
		$this->count = $count;	
	}
	
	private function setWB($bool){
		if(is_bool($bool)){
			$this->word_boundary = $bool;	
		}
	}
	
	private function setFlag($flag){
		if(in_array($flag,array("i","m","s","x","e"))){
			$this->flag = $flag;	
		}
	}
	
	private function setSplit($bool){
		if(is_bool($bool)){
			$this->split = $bool;	
		}
	}
	
	public function getResult(){
		return $this->output;
	}
	
	public function getCount(){
		return $this->count;
	}
}

then

include("class/class.search.php");
$search = "hEllO wOrLD"; //the input (is usually always different each time)
$phrase = "Hello World thenhelloinsode WorLD should DOwORld hellow HelLo WORldo";

/*
=======================PARAMETERS===========================
1: string:  search string [mandatory]
2: string:  content to search [mandatory]
3: string:  modifier for replacement: i,m,x,s,e, NULL [optional]
4: boolean: use split words as opposed to whole search term (true = use hello and world as opposed to hello world), NULL [optional]
5: boolean: use word boundaries for split words (true won't return matches inside other strings), NULL [optional]
6: string:  classname or b/strong or i/em for match styling, NULL [optional]
====================PUBLIC FUNCTIONS========================
getCount():		returns number of replacements
getResult():	returns replaced string

*/

$mysearch = new searchMe($search,$phrase,'i',true,false,'found2');
echo $mysearch->getResult();
echo "<br />There were {$mysearch->getCount()} replacements";

Anyway - simple usage:

include("class/class.search.php");
$search = $_POST['search']; //clean it?
$phrase = file_get_contents("indexes.txt");
$mysearch = new searchMe($search,$phrase);
echo $mysearch->getResult();

Not the safest bit of code though.