I have a string like <div><center>[content]</center></div>.
The "[content]" gets replaced by a php script that inserts a content from a database.
I've solved that problem by using the str_replace function. Now I want to modify my script like that: If I type [content] it should replace it. If I write [[content]] it shouldn't do anything. I thought about using regex but whatever I try -> It does not work.
If you don't understand me, just think back to c#, java,...: If I type \n, its a newline. If I type \n its "\n". I would be very thankfull if anyone could help.
Take a look at this example:
"aa[content]aa" -> aaMYCONTENTaa
"aa[[content]]aa" -> aa[[content]]aa
"aa[[[content]]]aa" -> aa[MYCONTENT]aa
Pure regex solution is possible, but you are heading on a dangerous path of building your own templating engine. There are several solutions available (smarty is the most popular one)
<?php
$str = preg_replace('([^\[]?)\[content\]([^\]]?)', '\1' . $yourcontent . '\2', $str);
?>
Explanation: [^\\[]? matches everything but the [ character, including nothing. This means [[content]] doesn't match.
EDIT:
the code will replace [content] with the $replace_content_with value unless it has [ before or ] after
$original = '<div><center>[content]</center></div>';
$replace_content_with = 'my new content';
$pattern = '/([^\[])\[content\]([^\]])/i';
$new_data = preg_replace($pattern, '\1'.$replace_content_with.'\2', $original);
echo $new_data; //print <div><center>my new content</center></div>
note that if your replacement content include \[SOME NUMBER] in it - it might not work as expected
Just replace '>[content]<' with '>whatever you want<'
Related
Before all: My english is not that good, so... I'd like to ask for apologizes if you guys can't understand me :)
So, this is what I'm looking for:
I'm being using a Wordpress plugin to generate XML (WP ALL EXPORT). Good.
Now, I need to open a file and edit some stuffs. I started with:
$data = file_get_contents("1439828483.xml");
And now I'm working using str_replace and preg_replace to update the lines I need.
I have two XML tag like these:
<cidade><![CDATA[sao-paulo>santo-andre]]></cidade>
<bairro><![CDATA[sao-paulo>santo-andre]]></bairro>
You see the content is the same... but it's because I have one ">" character splitting 2 stuff.
In the <cidade></cidade> tag I need to keep only what is before ">".
In the <bairro></bairro> tag I need to keep only what is after ">".
For the second problem, I fixed using this:
$data = preg_replace('#(<bairro>).*?(>)#', '$1$2', $data);
$data = str_replace('<bairro>>', "<bairro><![CDATA[",$data);
The result is:
<bairro><![CDATA[santo-andre]]></bairro>
OK, I have the content but it still have hyphens (dashes) and now I'm not able to fix it (No idea how to). What I really need is:
<bairro><![CDATA[santo andre]]></bairro>
And of course, for the tag <cidade></cidade> I would need to have:
<cidade><![CDATA[sao paulo]]></cidade>
Before posting here, I found this topic:
Regex between, from the last to specific end
But I tried to edit some parts of anubhava and Jack Maney answers but I failed :(
As I'm using preg_replace and str_replace I don't know if there is some limitations for regex strings.
Thanks and I hope you guys can understand me :D
This will do it (and replaces your own fix):
$data = preg_replace('#(<bairro><!\[CDATA\[)[^>]*?>([^>]*?><)#', '$1$2', $data);
while(preg_match('#(<bairro>[^->]*?)-([^->]*?-)*([^->]*?'.'>)#', $data)) {
$data = preg_replace('#(<bairro>[^->]*?)-(([^->]*?-)*)([^->]*?'.'>)#', '$1 $2$4', $data);
}
$data = preg_replace('#(<cidade><!\[CDATA\[[^>]*?)>[^>]*?(\]\]><)#', '$1$2', $data);
while(preg_match('#(<cidade>[^->]*?)-([^->]*?-)*([^->]*?'.'>)#', $data)) {
$data = preg_replace('#(<cidade>[^->]*?)-(([^->]*?-)*)([^->]*?'.'>)#', '$1 $2$4', $data);
}
Let me just point out that parsing XML with regex is often a bad idea, partly for reasons you're discovering. However, if all you want to do is replace hyphens with spaces, just do this:
$data = str_replace_all('-', " ", $data);
This will replace ALL the hyphens in your input, of course, so make sure you know what's in there.
The company I work for have asked me to give them the ability to place a modal box on the web page from the CMS, but do not want to type HTML. As I cannot for the life of me understand regex I can't get it.
The layout of the code they should type is this:
++modal++
Some paragraph text.
Another paragraph.
++endmodal++
The paragraphs are already converted by markdown into <p>paragraph</p>.
So really the match has to be ++modal++ any number of A-Za-z0-9any symbol excluding + ++endmodal++ then replaced with HTML.
I'm not sure it preg_match or preg_replace should be used.
I got this far:
$string = '++modal++<p>Hello</p>++endmodal++';
$pattern = '/\+\+modal\+\+/';
preg_match($pattern, $string, $matches);
Thank you in advance.
EDIT: A to be a bit more clear, I wish to replace the ++modal++ and ++endmodal++ with HTML and leave the middle bit as is.
I don't really think you need a RegEx here as your delimiters remain always the same and always on the same position of the string. Regular expressions are also expensive on resources and as a third counter argument you said you're not fit with them.
So why not use a simple replacement or string trimming if it comes to that.
$search = array('++modal++', '++endmodal++');
$replacement = array('<tag>', '</tag>');
$str = '++modal++<p>Hello</p>++endmodal++';
$result = str_replace($search, $replacement, $str);
Where, of course, '<tag>' and '</tag>' are just example placeholders for your replacement.
This is what the manual for str_replace() says:
If you don't need fancy replacing rules (like regular expressions),
you should always use this function instead of preg_replace().
I think you should get your desired content using:
preg_match('/\+\+modal\+\+([^\+]+)\+\+endmodal\+\+/', $string, $matches)
$matches[1] = '<p>Hello</p>
You're trying to re-invent the wheel here. You're trying to write a simple template system here, but there are dozens of templating tools for PHP that you could use, ranging from big and complex like Smarty and Twig to really simple ones that aren't much more than you're trying to write.
I haven't used them all, so rather than recommend one I'll point you to a list of template engines you could try. You'll probably find more with a quick bit of googling.
If you do insist on writing your own, it's important to consider security. If you're outputting anything that contains data entered by your users, you must make sure all your output is properly escaped and sanitised for display on a web page; there a numerous common hacks that can take advantage of an insecure templating system to completely compromise a site.
<?php
$string = '++modal++<p>Hello</p>++endmodal++';
$patterns = array();
$patterns[0] = "/\+\+modal\+\+/"; // put '\' just before +
$patterns[1] = "/\+\+endmodal\+\+/";
$replacements = array();
$replacements[1] = '<html>';
$replacements[0] = '</html>';
echo preg_replace($patterns, $replacements, $string);
?>
Very similar to this example
following code is used to find url from a string with php. Here is the code:
$string = "Hello http://www.bytes.com world www.yahoo.com";
preg_match('/(http:\/\/[^\s]+)/', $string, $text);
$hypertext = "" . $text[0] . "";
$newString = preg_replace('/(http:\/\/[^\s]+)/', $hypertext, $string);
echo $newString;
Well, it shows a link but if i provide few link it doesn't work and also if i write without http:// then it doesn't show link. I want whatever link is provided it should be active, Like stackoverflow.com.
Any help please..
A working method for linking with http/https/ftp/ftps/scp/scps:
$newStr = preg_replace('!(http|ftp|scp)(s)?:\/\/[a-zA-Z0-9.?&_/]+!', "\\0",$str);
I strongly advise NOT linking when it only has a dot, because it will consider PHP 5.2, ASP.NET, etc. links, which is hardly acceptable.
Update: if you want www. strings as well, take a look at this.
If you want to detect something like stackoverflow.com, then you're going to have to check for all possible TLDs to rule out something like Web 2.0, which is quite a long list. Still, this is also going to match something as ASP.NET etc.
The regex would looks something like this:
$hypertext = preg_replace(
'{\b(?:http://)?(www\.)?([^\s]+)(\.com|\.org|\.net)\b}mi',
'$1$2$3',
$text
);
This only matches domains ending in .com, .org and .net... as previously stated, you would have to extend this list to match all TLDs
#axiomer your example wasn't work if link will be in format:
https://stackoverflow.com?val1=bla&val2blablabla%20bla%20bla.bl
correct solution:
preg_replace('!(http|ftp|scp)(s)?:\/\/[a-zA-Z0-9.?%=&_/]+!', "\\0", $content);
produces:
https://stackoverflow.com?val1=bla&val2blablabla%20bla%20bla.bl
I am trying to get the page or last directory name from a url
for example if the url is: http://www.example.com/dir/ i want it to return dir or if the passed url is http://www.example.com/page.php I want it to return page Notice I do not want the trailing slash or file extension.
I tried this:
$regex = "/.*\.(com|gov|org|net|mil|edu)/([a-z_\-]+).*/i";
$name = strtolower(preg_replace($regex,"$2",$url));
I ran this regex in PHP and it returned nothing. (however I tested the same regex in ActionScript and it worked!)
So what am I doing wrong here, how do I get what I want?
Thanks!!!
Don't use / as the regex delimiter if it also contains slashes. Try this:
$regex = "#^.*\.(com|gov|org|net|mil|edu)/([a-z_\-]+).*$#i";
You may try tho escape the "/" in the middle. That simply closes your regex. So this may work:
$regex = "/.*\.(com|gov|org|net|mil|edu)\/([a-z_\-]+).*/i";
You may also make the regex somewhat more general, but that's another problem.
You can use this
array_pop(explode('/', $url));
Then apply a simple regex to remove any file extension
Assuming you want to match the entire address after the domain portion:
$regex = "%://[^/]+/([^?#]+)%i";
The above assumes a URL of the format extension://domainpart/everythingelse.
Then again, it seems that the problem here isn't that your RegEx isn't powerful enough, just mistyped (closing delimiter in the middle of the string). I'll leave this up for posterity, but I strongly recommend you check out PHP's parse_url() method.
This should adequately deliver:
substr($s = basename($_SERVER['REQUEST_URI']), 0, strrpos($s,'.') ?: strlen($s))
But this is better:
preg_replace('/[#\.\?].*/','',basename($path));
Although, your example is short, so I cannot tell if you want to preserve the entire path or just the last element of it. The preceding example will only preserve the last piece, but this should save the whole path while being generic enough to work with just about anything that can be thrown at you:
preg_replace('~(?:/$|[#\.\?].*)~','',substr(parse_url($path, PHP_URL_PATH),1));
As much as I personally love using regular expressions, more 'crude' (for want of a better word) string functions might be a good alternative for you. The snippet below uses sscanf to parse the path part of the URL for the first bunch of letters.
$url = "http://www.example.com/page.php";
$path = parse_url($url, PHP_URL_PATH);
sscanf($path, '/%[a-z]', $part);
// $part = "page";
This expression:
(?<=^[^:]+://[^.]+(?:\.[^.]+)*/)[^/]*(?=\.[^.]+$|/$)
Gives the following results:
http://www.example.com/dir/ dir
http://www.example.com/foo/dir/ dir
http://www.example.com/page.php page
http://www.example.com/foo/page.php page
Apologies in advance if this is not valid PHP regex - I tested it using RegexBuddy.
Save yourself the regular expression and make PHP's other functions feel more loved.
$url = "http://www.example.com/page.php";
$filename = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_FILENAME);
Warning: for PHP 5.2 and up.
I wrote a little search script for a client, it works and words get highlited, BUT...
Imagine this situation:
search term: test
found result: Hello this is a test
In this example both 'test' in the href part and between the <a> tags get highlited, breaking the link.
How could I prevent this?
Edit:
So this is what I need: A regex replace function that replaces all matched search strings EXCEPT the ones that are located inside a href attribute
You can not parse XML with regular expressions. :( If you want a dirty regex solution that still works in many cases you may try this regex.
">[^<]*?(test)"
First you look for a tag closing brace and than you make sure that no other tag is opened in between.
Ideally you want to parse HTML and replace only the textual parts of it.
Got it!
$body = $row['body'];
$pattern = "/".$search_string."(?!([^<]+)?>)/i";
$replacement = "<strong class='highlite'>".$search_string."</strong>";
$altered_body = preg_replace($pattern, $replacement, $body);
print($altered_body);