I have a table in MySQL that contains couple of expressions that I want to pass to preg_replace
My code:
$q = mysql_query("SELECT * FROM TABLE");
while($r=mysql_query($q)) {
$expressions = $r['expressions'];
}
$expressions = explode("\n", $expressions);
foreach ($expressions as $expression) {
$content = preg_replace($expression, '', $content);
}
Some data in database:
#<div class="FBTbtn">(.*?)</div>#
#<!-- Extra Link -->(.*?)<!-- End Of Extra Link -->#
#<a(.*?)/a>#
#Learn More:#
As described on the mysql_query() function page, iterate through the results with mysql_fetch_assoc(). http://php.net/manual/en/function.mysql-query.php
$content = 'foo bar baz';
$result = mysql_query("SELECT * FROM expressions");
while ($row = mysql_fetch_assoc($result)) {
$content = preg_replace($row['expression'], '', $content);
}
By the way, mysql_*() functions are deprecated. You should switch to PDO.
http://php.net/manual/en/book.pdo.php
I fixed the it by using "," instead of "\n"
Code:
$q = mysql_query("SELECT * FROM TABLE");
while($r=mysql_query($q)) {
//Remove last "," from string
$expressions = rtrim($r['expressions'], ",");
}
//Explode string into array based on "," instead of "\n"
$expressions = explode(",", $expressions);
foreach ($expressions as $expression) {
$content = preg_replace($expression, '', $content);
}
Data in database should look like:
#<div class="FBTbtn">(.*?)</div>#,#<!-- Extra Link -->(.*?)<!-- End Of Extra Link -->#,#<a(.*?)/a>#,#Learn More:#,
Related
I have multiple strings with same curly braces I want to replace them as dynamic if I get the count as 1 then need to replace the first occurrence, If count as 2 then replaces the second occurrence as so on until condition satisfies.
<?php
include_once("con.php");
$db = new Da();
$con = $db->con();
$String = "{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}";
$Count = 1;
if(preg_match_all("/\{\{[^{}]+\}\}/", $lclString, $matches)) {
foreach ($matches[0] as $match) {
$Count++;
$Query = "SELECT link FROM student WHERE linkVal = '".$match."'";
$Result = $con->query($Query);
if($row = $Result->fetch(PDO::FETCH_ASSOC)) {
$NewValue = preg_replace("/\{\{[^{}]+\}\}/", $row["link"], $String);
}
}
echo json_encode($NewValue);
}
?>
If first occurrence the {{ONE}} should replace with new value with $row["link"],
Secondly replace {{TWO}} With New value so on.
Within the loop on each match, instead of using preg_replace, I suggest you to use str_replace:
if(preg_match_all("/\{\{[^{}]+\}\}/", $lclString, $matches)) {
$NewValue = $String;
foreach ($matches[0] as $match) {
$Count++;
$Query = "SELECT link FROM student WHERE linkVal = '".$match."'";
$Result = $con->query($Query);
if($row = $Result->fetch(PDO::FETCH_ASSOC)) {
$NewValue = str_replace($match, $row["link"], $NewValue);
// ^^^^^^^^^^^^^^^^^^
}
}
echo json_encode($NewValue);
}
You can greatly simplify your code by fetching all the replacement values in one query:
$String = "{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}";
if(preg_match_all("/\{\{[^{}]+\}\}/", $String, $matches)) {
$Query = "SELECT linkVal, link FROM student WHERE linkVal IN('".implode("','", $matches[0])."')";
$Result = $con->query($Query);
if ($rows = $Result->fetchAll(PDO::FETCH_ASSOC)) {
$NewValue = str_replace(array_column($rows, 'linkVal'), array_column($rows, 'link'), $String);
}
echo json_encode($NewValue);
}
You can use preg_replace_callback to iterate through your matches.
e.g.
$str = "{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}";
$replaced = preg_replace_callback('/{{([^{}]*)}}/', function($match) {
// $match[1] contains the current match (first capture group) e.g. ONE
// return your replacement for the current match, e.g. reversed string ENO
return strrev($match[1]);
}, $str);
echo $replaced;
Output will be ENO OWT EERHT RUOF EVIF XIS
There are a few issues with your code, you need to ensure that the variable in the preg_match_all() is the string your trying to search.
But the main problem is in the replacement part. You need to replace the current match value ($match) and replace it in a new string - currently you always replace the new match in the original string. Here I create $NewValue from the original string and keep replacing values in that...
if(preg_match_all("/\{\{[^{}]+\}\}/", $String, $matches)) {
$NewValue = $String;
foreach ($matches[0] as $match) {
$Count++;
$Query = "SELECT link FROM student WHERE linkVal = '".$match."'";
$Result = $con->query($Query);
if($row = $Result->fetch(PDO::FETCH_ASSOC)) {
$NewValue = preg_replace("/".preg_quote($match)."/",
$row["link"], $NewValue);
}
}
echo json_encode($NewValue);
}
You should also look into using prepared statements as currently you may be open to SQL Injection problems.
The expression we might wish to design here can be like one of these:
({{)(.+?)(}})
which is only using capturing groups ().
DEMO 1
(?:{{)(.+?)(?:}})
and here we can use non-capturing groups (?:), if we do not wish to keep the {{ and }}.
DEMO 2
Then, we could simply do the preg_replace that we wanted to do.
Test
$re = '/(?:{{)(.+?)(?:}})/m';
$str = '{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}';
$subst = '$1';
$result = preg_replace($re, $subst, $str);
echo "The result of the substitution is ".$result;
I have the code:
mysql_connect('...');
mysql_select_db('...');
$result = mysql_query('SELECT `oldword`, `newword` FROM `#_words`');
$find = array();
$replace = array();
while ($row = mysql_fetch_assoc($result)) {
$find[] = $row['oldword'];
$replace[] = $row['newword'];
}
$oldstring = 'Some text';
$newstring = str_replace($find, $replace, $oldstring);
echo $newstring;
It works good but there are two problems. First I need to convert it for using Joomla API i.e. to something like
$db = &JFactory::getDBO();
$db->setQuery('SELECT `oldword`, `newword` FROM `#_words`');
// and what is next, what about mysql_fetch_assoc ?
And secondly, if oldword and newword are english it works but if cyrillic it doesn't. How can I fix it? I have tried this:
function fixEncoding($s, $encoding = 'UTF-8') {
$s = #iconv('UTF-16', $encoding . '//IGNORE', iconv($encoding, 'UTF-16//IGNORE', $s));
return str_replace("\xEF\xBB\xBF", '', $s);
}
$find = fixEncoding($find);
$replace = fixEncoding($replace);
but this function works with a single string only and doesn't work with array
I would have to do some testing regarding the cyrillic problem, but as for your database query using Joomla coding standards, it will look like this:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('oldword', 'newword')))
->from($db->quoteName('#__words'));
$db->setQuery($query);
$results = $db->loadAssocList();
$find = array();
$replace = array();
foreach ( $results as $row ) {
$find[] = $row->oldword;
$replace[] = $row->newword;
}
$oldstring = 'Some text';
$newstring = str_replace($find, $replace, $oldstring);
echo $newstring;
In my PHP forum i want people to insert pictures just by inserting the number/ID of the picture (which they can see in an online photoalbum)
I am looking for a function that can read a string from their posts for example
"bla bla and look at this amazing picture [IMG]234[/IMG] isn't it awesome ..."
then finds the picture in a database with the ID 234 and replaces [IMG]234[/IMG] with
<img src = "path/to/image.jpg" />
preg_replace wouldn't work :( does anyone have an Idea?
thanks for Your help in advance
I would do it in this way:
$images = array();
$post = preg_replace_callback('|\[img\](\d+)\[/img\]|i', function($matches) use(&$images) {
$images[] = $matches[1];
return '__image_' . $matches[1];
}, $post);
if (count($images)) {
// Select images
$imageIds = implode(',', $images);
// DB query
$res = mysql_query("SELECT id, path FROM post_images WHERE id IN ({$imageIds})") or die(mysql_error());
// Replace
while (($row = mysql_fetch_assoc($res))) {
$post = str_replace('__image_'.$row['id'], '<img src=' . $row['path'] . ' />', $post);
}
}
The advantage is that you make only one query to database. This is always important to minimize them to increase performance. if you don't care or you are sure that the number of images in not going to be too high, you can simple use this code:
$post = preg_replace_callback('|\[img\](\d+)\[/img\]|i', function($matches) {
$res = mysql_query("SELECT path FROM post_images WHERE id = {$matches[1]}") or die(mysql_error());
$path = mysql_result($res, 0);
return "<img src='$path' />";
}, $post);
here is what i did:
$find = preg_match_all("!\[img\][0-9]+\[\/img\]!", $post, $matches);
foreach ($matches as $match) {
foreach ($match as $ma) {
$res = str_replace("[/img]","", str_replace("[img]", "",$ma));
$query = "
SELECT
path
FROM
table
WHERE id = '".$res."'
";
$result = mysql_query($query, $conn) or die(mysql_error());
while($line = mysql_fetch_array($result)) {
$path = $line["path"];
$path = "<img src = '".$path. "'></img>";
$post = str_replace ("[img]" . $res . "[/img]", $path, $post);
}
}
}
note: i don't know why preg_match_all creates a 2 depths array
Your code needs to make a db call to get the path from the ID.
Use a tag parser or basic regex to match \[img][0-9]+\[/img]. (preg_match)
Then query your database for the path with the match result as the ID.
Finally, use str_replace to replace the original "[img]$match[/img]" with
Example (pseudo, look these functions up first)
$matches = preg_match_all('\[img][0-9]+\[/img]', $input);
$output = $input;
foreach ($matches as $match) {
$cur = mysql_query("SELECT path FROM table WHERE ID = $match");
$row = mysql_fetch_array($cur);
$output = str_replace('[img]'.$match.'[/img]',$row['path'],$output);
}
Note: this will only work with tags in lowercasse: img and not with IMG, iMG, ImG and so on.
Why doesn't preg_replace work? Not knowing the the details, I would guess that you are not escaping the square brackets. What does your regular expression look like? Try something like
/\[IMG\](\d+)\[/IMG]/
The image id will then be in the group 1, i.e. $1.
Example:
preg_match_all('/\[IMG\](\d+)\[/IMG]/', $post, $matches);
foreach ($matches as $match) {
echo "Image number: " . $match[1] . "\n";
}
I have a PHP search script that queries a MySQL database and then parses the results through HTML to allow CSS styling. I want the script to highlight all of the keywords in the results that the user has search for. How can I do this with PHP?
My PHP script is:
<?php
mysql_connect("localhost","username","password");
mysql_select_db("database");
if(!empty($_GET['q'])){
$query=mysql_real_escape_string(trim($_GET['q']));
$searchSQL="SELECT * FROM links WHERE `title` LIKE '%{$query}%' LIMIT 8";
$searchResult=mysql_query($searchSQL);
while ($row=mysql_fetch_assoc($searchResult)){
$results[]="<a href='{$row['url']}' class='webresult'><div class='title'>{$row['title']}</div><div class='desc'>{$row['description']}</div><div class='url'>{$row['url']}</div></a>";
}
if(empty($results)){
echo 'No results were found';
} else {
echo implode($results);
}
}
?>
Simplistically you could adapt the loop here:
$searchvar = trim($_GET['q']);
while ($row=mysql_fetch_assoc($searchResult)){
$description = str_replace($searchvar, '<span class="highlight">'.$searchvar."</span>", $row['description']);
$results .="<a href='{$row['url']}' class='webresult'>
<div class='title'>{$row['title']}</div>
<div class='desc'>{$description}</div>
<div class='url'>{$row['url']}</div></a>";
}
To make it a little better:
$searchvar = explode(" ", trim($_GET['q'])); //puts each space separated word into the array.
while ($row=mysql_fetch_assoc($searchResult)){
$description = $row['description'];
foreach($searchvar as $var) $description = str_replace($var, '<span class="highlight">'.$var."</span>", $description);
$description = str_replace($searchvar, '<span class="highlight">'.$searchvar."</span>", $row['description']);
$results .="<a href='{$row['url']}' class='webresult'>
<div class='title'>{$row['title']}</div>
<div class='desc'>{$description}</div>
<div class='url'>{$row['url']}</div></a>";
}
The benefit of the second one there is that if a user types in "ipod toudch yellow" you will be searching for "ipod", "toudch" and "yellow" which would negate the type and make the results more general.
You would need to exchange the single:
like '%query%'
with
foreach(explode(" ", trim($_GET['q']) as $searchvar) $where[] = "like '%$searchvar%'";
$wheresql = implode(" OR ", $where);
to get each search "word" to be looked for in the sql or you will have a limited search with a unrelated highlight.
i also found this solution to highlight each word of the results:
$text = $searchresults;
class highlight
{
public $output_text;
function __construct($text, $words)
{
$split_words = explode( " " , $words );
foreach ($split_words as $word)
{
$text = preg_replace("|($word)|Ui" , "<b>$1</b>" , $text );
}
$this->output_text = $text;
}
}
$highlight = new highlight($searchresults, $keywords);
echo $highlight;
In case that could help,
Regards,
Max
you can use regex or simply str replace to look for a particular string and add a span around it:
while ($row=mysql_fetch_assoc($searchResult)){
$str ="<a href='".$row['url']."' class='webresult'>";
$str .="<div class='title'>".$row['title']."</div>";
$str .="<div class='desc'>";
$str .= str_replace($query,"<span class='hightlighted'>".$query."</span>",$row['description']);
$str .="</div><div class='url'>".$row['url']."</div></a>";
$result[] = $str;
}
now the css:
span.highlighted {
background-color: yellow;
}
You can use str_replace. For each keyword the user uses, put it into the $search array, and also put it into a $replace array, but surround with with a classed span tag in the latter, which you can style with CSS later. For example:
$search = array('apple', 'orange');
$replace = array();
foreach ($search as $word)
{
$replace[] = "<span class='highlight'>$word</span>";
}
$string = str_replace($search, $replace, $string);
EDIT: assuming that $query just contains keywords delimited by a single whitespace, you could get the search array this way (with explode),
$search = explode(' ', $query);
Or, if you want to add more complex logic for processing the keywords out of the $query variable (like if you use query operators like +), you could use a for loop:
$queryTerms = explode(' ', $query);
$search = array();
foreach ($queryTerms as $term)
{
// do some processing of the $term (like delete "+"?)
// ...
$search[] = $processedTerm;
}
I'm trying to remove some excessive indention from a string, in this case it's SQL, so it can be put into a log file. So I need the find the smallest amount of indention (aka tabs) and remove it from the front of each line, but the following code ends up printing out exactly the same, any ideas?
In other words, I want to take the following (NOTE: StackOverflow editor converted my tabs to spaces, in the code, a tab simulates 4 spaces, but it really is a \t character)
SELECT
blah
FROM
table
WHERE
id=1
and convert it to
SELECT
blah
FROM
table
WHERE
id=1
here's the code I tried and fails
$sql = '
SELECT
blah
FROM
table
WHERE
id=1
';
// it's most likely idented SQL, remove any idention
$lines = explode("\n", $sql);
$space_count = array();
foreach ( $lines as $line )
{
preg_match('/^(\t+)/', $line, $matches);
$space_count[] = strlen($matches[0]);
}
$min_tab_count = min($space_count);
$place = 0;
foreach ( $lines as $line )
{
$lines[$place] = preg_replace('/^\t{'. $min_tab_count .'}/', '', $line);
$place++;
}
$sql = implode("\n", $lines);
print '<pre>'. $sql .'</pre>';
It seems the problem was
strlen($matches[0])
returns 0 and 1 for the first and last line, which isn't the 3 I actually wanted as the minimum, so a quick hack was to
trim the SQL
skip counting the length if it's less than 2
Not the most elegant solution, but it'll always work because tabs are usually in the 4+ count in this code. Here's the fixed code:
$sql = '
SELECT
blah
FROM
table
WHERE
id=1
';
// it's most likely idented SQL, remove any idention
$lines = explode("\n", $sql);
$space_count = array();
foreach ( $lines as $line )
{
preg_match('/^(\t+)/', $line, $matches);
if ( strlen($matches[0]) > 1 )
{
$space_count[] = strlen($matches[0]);
}
}
$min_tab_count = min($space_count);
$place = 0;
foreach ( $lines as $line )
{
$lines[$place] = preg_replace('/^\t{'. $min_tab_count .'}/', '', $line);
$place++;
}
$sql = implode("\n", $lines);
print $sql;
private function cleanIndentation($str) {
$content = '';
foreach(preg_split("/((\r?\n)|(\r\n?))/", trim($str)) as $line) {
$content .= " " . trim($line) . PHP_EOL;
}
return $content;
}