I need to remove string inside [...] including "[]" itself. I tried searching for a solution from this site. I have a clue that I should try something with preg_replace but it seems too expert to me.
For example :
[gallery ids="92,93,94,95,96,97,98,99,100" orderby="rand"] Description The thirty-two storey resort condominium in Phuket, located Just 150m from Patong beach where choices of activities, water sp
I need to remove [gallery ids="92,93,94,95,96,97,98,99,100" orderby="rand"] from the example text. And it always begins with [gallery ids=" .
Please suggest.
Try this:
$string = '[gallery ids="92,93,94,95,96,97,98,99,100" orderby="rand"] Description The thirty-two storey resort condominium in Phuket, located Just 150m from Patong beach where choices of activities, water sp ';
$string = preg_replace('/\[gallery ids=[^\]]+\]/', '', $string);
Breakdown:
\[gallery ids= look for substring that begins with [gallery ids=
[^\]]+\] match 1 or more characters that are not ] until you reach a ]
Will then replace that whole matched portion with '' nothing and you have your new string.
Related
So I'm trying to make a php function to get HTML tags from a BBCode-style form. The fact is, I was able to get tags pretty easily with preg_replace. But I have some troubles when I have a bbcode inside the same bbcode...
Like this :
[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]
So, when I "parse" it, I always have remains bbcode for the blue ones. Something like :
My house is [blue]very[/blue] beautiful today
Everything is colored except for the blue-tag inside the black-tag inside the first blue-tag.
How the hell can I do that ?
With more informations, I tried :
Regex: "/\[blue\](.*)\[\/blue\]/si" or "/\[blue\](.*)\[\/blue\]/i"
Getting : "My house is [blue]very[/blue] beautiful today"
Regex : "/\[blue\](.*?)\[\/blue\]/si" or "/\[blue\](.*)\[\/blue\]/Ui"
Getting : "My house is [blue]very beautiful today[/blue]"
Do I have to loop the preg_replace ? Isn't there a way to do it, regex-style, without looping the thing ?
Thx for your concern. :)
It is right that you should not reinvent the wheel on products and rather choose well-tested plugins. However, if you are experimenting or working on pet projects, by all means, go ahead and experiment with things, have fun and obtain important knowledge in the process.
With that said, you may try following regex. I'll break it down for you on below.
(\[(.*?)\])(.*?)(\[/\2\])
Philosophy
While parsing markup like this, what you are actually seeking is to match tags with their pairs.
So, a clean approach you can take would be running a loop and capturing the most outer tag pair each time and replacing it.
So, on the given regex above, capture groups will give you following info;
Opening tag (complete) [black]
Opening tag (tag name) black
Content between opening and closing tag My [black]house is [blue]very[/blue] beautiful[/black] today
Closing tag [/blue]
So, you can use $2 to determine the tag you are processing, and replace it with
<tag>$3</tag>
// or even
<$2>$3</$2>
Which will give you;
// in first iteration
<tag>My [black]house is [blue]very[/blue] beautiful[/black] today</tag>
// in second iteration
<tag>My <tag2>house is [blue]very[/blue] beautiful</tag2> today</tag>
// in third iteration
<tag>My <tag2>house is <tag3>very</tag3> beautiful</tag2> today</tag>
Code
$text = "[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]";
function convert($input)
{
$control = $input;
while (true) {
$input = preg_replace('~(\[(.*?)\])(.*)(\[/\2\])~s', '<$2>$3</$2>', $input);
if ($control == $input) {
break;
}
$control = $input;
}
return $input;
}
echo convert($text);
As others mentionned, don't try to reinvent the wheel.
However, you could use a recursive approach:
<?php
$text = "[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]";
$regex = '~(\[ ( (?>[^\[\]]+) | (?R) )* \])~x';
$replacements = array( "blue" => "<bleu>",
"black" => "<noir>",
"/blue" => "</bleu>",
"/black" => "</noir>");
$text = preg_replace_callback($regex,
function($match) use ($replacements) {
return $replacements[$match[2]];
},
$text);
echo $text;
# <bleu>My <noir>house is <bleu>very</bleu> beautiful</noir> today</bleu>
?>
Here, every colour tag is replaced by its French (just made it up) counterpart, see a demo on ideone.com. To learn more about recursive patterns, have a look at the PHP documentation on the subject.
In my script I replaced all "," commas with quotation+spaces.
But when it comes to numbers which are like 3,456,778, it also converts the commas to quote+space. Is there any way to add to command to ignore big numbers like that so it doesn't convert it to:
3" 456" 778"
If there is quotationm+space+any number then convert quotation+space to comma.. I mean i know how to do it with str_replace command but i dont know how to select anynumber 0-9.
Any help to do it? To convert it to:
3,456,778
I think i need to elaborate some. I needed convert this text:
Value=3,456,778,id=777
To:
Value=3,456,778" id=777"
But problem is it also convert those middle commas in between numbers.
So even if I can change my str_replace command to this like
"If comma is not in between two numbers then only convert comma to quotation+space". It would be good. Is it possible?
What about this?
preg_replace("/,([^0-9]|$)/", "\"$1", $text);
This will match all the text except commas followed by numbers.
For instance, this:
$text = "123,23 adas , asdsa d, asdasd sa 1234,234324,asdas 324324 234,";
echo $text; echo "<br/>";
echo preg_replace("/,([^0-9]|$)/", "\"$1", $text);
Will echo this:
123,23 adas , asdsa d, asdasd sa 1234,234324,asdas 324324 234"
123,23 adas " asdsa d" asdasd sa 1234,234324"asdas 324324 234"
It is not really clear from your description what you actually want to do.
This might be a step into the right direction, however:
preg_replace('/([0-9]+)" /', '\\1,', '3" 456" 778"');
Not the best solution maybe,but can give it a try.
$copy_date = '3" 456" 778"';
$copy_date = preg_replace("(\"\s{1})", ",", $copy_date);
$copy_date1 = preg_replace("(\")", "", $copy_date);
print $copy_date1;
o/p:3,456,778
This is the string
(code)
Pivot: 96.75<br />Our preference: Long positions above 96.75 with targets # 97.8 & 98.25 in extension.<br />Alternative scenario: Below 96.75 look for further downside with 96.35 & 95.9 as targets.<br />Comment the pair has broken above its resistance and should post further advance.<br />
(text)
"Pivot: 96.75Our preference: Long positions above 96.75 with targets # 97.8 & 98.25 in extension.Alternative scenario: Below 96.75 look for further downside with 96.35 & 95.9 as targets.Comment the pair has broken above its resistance and should post further advance."
the result should be
(code)
<b>Pivot</b>: 96.75<br /><b>Our preference</b>: Long positions above 96.75 with targets # 97.8 & 98.25 in extension.<br /><b>Alternative scenario</b>: Below 96.75 look for further downside with 96.35 & 95.9 as targets.<br />Comment the pair has broken above its resistance and should post further advance.<br />
(text)
Pivot: 96.75Our preference: Long positions above 96.75 with targets # 97.8 & 98.25 in extension.Alternative scenario: Below 96.75 look for further downside with 96.35 & 95.9 as targets.Comment the pair has broken above its resistance and should post further advance.
The porpuse:
Wrap all the words before : sign.
I've tried this regex: ((\A )|(<br />))(?P<G>[^:]*):, but its working only on python environment. I need this in PHP:
$pattern = '/((\A)|(<br\s\/>))(?P<G>[^:]*):/';
$description = preg_replace($pattern, '<b>$1</b>', $description);
Thanks.
This preg_replace should do the trick:
preg_replace('#(^|<br ?/>)([^:]+):#m','$1<b>$2</b>:',$input)
PHP Fiddle - Run (F9)
I should start by saying that HTML operations are better done with a proper parser such as DOMDocument. This particular problem is straightforward, so regular expressions may work without too much hocus pocus, but be warned :)
You can use look-around assertions; this frees you from having to restore the neighbouring strings during the replacement:
echo preg_replace('/(?<=^|<br \/>)[^:]+(?=:)/m', '<b>$0</b>', $str);
Demo
First, the look-behind assertion matches either the start of each line or a preceding <br />. Then, any characters except the colon are matched; the look-ahead assertion makes sure it's followed by a colon.
The /m modifier is used to make ^ match the start of each line as opposed to \A which always matches the start of the subject string.
The most "general" and least regex-expensive way to do this that I could come up with was this:
$parts = explode('<br', $str);//don't include space and `/`, as tags may vary
$formatted = '';
foreach($parts as $part)
{
$formatted .= preg_replace('/^\s*[\/>]{0,2}\s*([^:]+:)/', '<b>$1</b>',$part).'<br/>';
}
echo $formatted;
Or:
$formatted = array();
foreach($parts as $part)
{
$formatted[] = preg_replace('/^\s*[\/>]{0,2}\s*([^:]+:)/', '<b>$1</b>',$part);
}
echo implode('<br/>', $formatted);
Tested with, and gotten this as output
Pivot: 96.75Our preference: Long positions above 96.75 with targets # 97.8 & 98.25 in extension.Alternative scenario: Below 96.75 look for further downside with 96.35 & 95.9 as targets.Comment the pair has broken above its resistance and should post further advance.
That being said, I do find this bit of data weird, and, if I were you, I'd consider str_replace or preg_replace-ing all breaks with PHP_EOL:
$str = preg_replace('/\<\s*br\s*\/?\s*\>/i', PHP_EOL, $str);//allow for any form of break tag
And then, your string looks exactly like the data I had to parse, and got the regex for that here:
$str = preg_replace(...);
$formatted = preg_replace('/^([^:\n\\]++)\s{0,}:((\n(?![^\n:\\]++\s{0,}:)|.)*+)/','<b>$1:</b>$2<br/>', $str);
In PHP I have a String $string and an array $acronyms (in the form "UK" => "United Kingdom").
Now I want to replace all acronyms within $string by some HTML Tags. For example Hello UK should turn into Hello <acronym title="United Kingdom">UK</acronym></pre>
I do it this way:
foreach($acronyms as $acronym => $tooltip){
$string = preg_replace('/'.$acronym.'/i', ''.$acronym.'', $string);
}
The problem is: Let's say I have a text Hello UK and have an array to replace "UK" with "United Kingdom" and "Kingdom" with "RandomWord". Then the text will replace into Hello <acronym title="United <acronym title="RandomWord">Kingdom</acronym>">UK</acronym> which obviously is chaos.
So the question is: How do I make my preg_replace only look for the words while they are NOT within an <acronym> tag? (neither in title-attribute, nor within the tag itself)
Edit: second attempt according to a response (because I can't put code in reply). Still the same problem, the text within acronym gets replaced a second time...
foreach($acronyms as $acronym => $tooltip){
$acronyms[$acronym] = '<acronym title="'.$tooltip.'">'.$acronym.'</acronym>';
}
$string = str_ireplace(array_keys($acronyms), array_values($acronyms), $string);
You can use strtr(). It doesn't rescan the string after performing a replacement:
foreach ($acronyms as $acronym => $tooltip) {
$acronyms[$acronym] = sprintf('<acronym title="%s">%s</acronym>',
htmlspecialchars($tooltip),
htmlspecialchars($acronym)
);
}
echo strtr($str, $acronyms);
Here's an attempt at the regex version:
foreach($acronyms as $acronym => $tooltip){
$rexp = '/' . $acronym . '(?!((?!<acronym).)*<\/acronym>)/i';
$string = preg_replace($rexp, ''.$acronym.'', $string);
}
Seems to work for me. It does the following:
Match the $acronym variable with a negative look ahead...
where a closing acronym tag can be found
but stop the lookahead when an opening acronym tag is before it.
Ultimately this matches only where it's not within an acronym tag (including all attributes such as the title).
Here's an example of it in action: gSkinner regex example
Don't try to do everything with regexes :
Parse your HTML using a HTML/XML parsing library.
Iterate over your HTML tags, replace what you have to replace.
Ask your "html parsing lib" to convert this back to a "HTML string".
This is the content of one mysql table field:
Flash LEDs: 0.5W
LED lamps: 5mm
Low Powers: 0.06W, 0.2W
Remarks(1): this is remark1
----------
Accessories: Light Engine
Lifestyle Lights: Ambion, Crane Fun
Office Lights: OL-Deluxe Series
Street Lights: Dolphin
Retrofits: SL-10A, SL-60A
Remarks(2): this is remark2
----------
Infrared Receiver Module: High Data Rate Short Burst
Optical Sensors: Ambient Light Sensor, Proximity Sensor, RGB Color Sensor
Photo Coupler: Transistor
Remarks(3): this is remark3
----------
Display: Dot Matrix
Remarks(4): this is remark4
Now, I want to read the remarks and store them in a variable. Remarks(1), Remarks(2), etc. are fixed. 'this is remark1', etc. come from form input fields, so they are flexible.
Basically what I need is: Read everything between 'Remarks(1):' and '--------' and save it in a variable.
Thanks for your help.
You can use regex:
preg_match_all("~Remarks\(([^)]+)\):([^\n]+)~", $str, $m);
As seen on ideone.
The regex will put X in match group 1, Y in match group 2 (Remarks(X): Y)
This would be a job for regular expressions, which allow you to match on exactly the kinds of rules your requirements express. Here is a tutorial for you.
Use preg function for this or otherwise you can explode and implode function to get correct result. Don't Use Substring it may not provide correction.
Example of Implode and Explode Function for your query string :
$sdr = "Remarks(4): this is remark4";
$sdr1 = explode(":",$sdr);
$frst = $sdr1[0];
$sdr2 = array_shift($sdr1);
$secnd = implode(" ", $sdr1);
echo "First String - ".$frst;
echo "<br>";
echo "Second String - ".$secnd;
echo "<br>";
Your Answer :
First String - Remarks(4)
Second String - this is remark4