There's a set of code I've used for a while to find strings into a file. But when I put it into a function, I don't get results and I think that it's preg_match_all that is not working. I don't know how to get this fixed.
Here's my code (copy/pasted from a tutorial):
function getprice($keyword, $outputvar) {
$pattern = preg_quote($keyword, '/');
$pattern = "/^.*$pattern.*\$/m";
echo "pattern:" . $pattern;
if(preg_match_all($pattern, $contents, $matches)){
$str=implode("\n", $matches[0]);
$str = substr( $str, ( $pos = strpos( $str, ':' ) ) === false ? 0 : $pos + 1 );
$$outputvar = $str;
}
else {
$$outputvar = "99999";
}
}
Not sure what you're trying to do with $outputvar and $$outputvar, but don't use them. return something. Also, $contents needs to be passed in:
function getprice($keyword, $contents) {
$pattern = preg_quote($keyword, '/');
$pattern = "/^.*$pattern.*\$/m";
if(preg_match_all($pattern, $contents, $matches)){
$str = implode("\n", $matches[0]);
$str = substr( $str, ( $pos = strpos( $str, ':' ) ) === false ? 0 : $pos + 1 );
return $str;
}
else {
return "99999";
}
}
Then use:
$outputvar = getprice($some_keyword, $some_contents);
This only addresses the use of the function, not your regex or the data that is parsed, as you haven't posted any test cases.
Related
I have:
$string = 'Hello x World hello';
And I want to remove the first instance of a term that is case insensitive.
For example, I have:
$term = 'hello';
And I want to match it with $string, so we end up with:
$string = ' x World hello';
What I've done so far
I am nearly there! I can replace the first instance of a term with:
function str_replace_once($str_pattern, $str_replacement, $string){
if (strpos($string, $str_pattern) !== false){
$occurrence = strpos($string, $str_pattern);
return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern));
}
return $string;
}
But it is not case insensitive, see ideone. How can I make it case insensitive?
In your example code, just replace strpos with stripos... (with a few minor tweaks)...
function str_replace_once($str_pattern, $str_replacement, $string){
$pos = stripos($string, $str_pattern);
if ($pos !== false){
return substr_replace($string, $str_replacement, $pos, strlen($str_pattern));
}
return $string;
}
I wish str_ireplace had a limit, it would be better. But preg_replace has a limit. Use the i modifier for case-insensitive:
$string = preg_replace("/$term/i", "", $string, 1);
Also note that there is a stripos which is case-insensitive strpos which you can use in your existing code.
Use stripos(case-insensitive) and substr
function str_replace_first($str, $search, $replace)
{
$index = stripos($str, $search);
return $index === false ? $str : substr($str, 0, $index) . $replace . substr($str, $index + strlen($search));
}
Usage:
$string = 'Hello x World hello';
echo str_replace_first($string,'Hello', '');
I have a series of tag in the text that I want to match with preg_match_all but the $regex string has something wrong and I can't understand what to do.
$tagReplace = ['mov', 'flv', 'youtube'];
foreach ($tagReplace as $plg_tag) {
$regex = "#{" . $plg_tag . "}(.*?){/" . $plg_tag . "}#s";
$var = preg_match_all($regex, "{mov}the_video_url{/mov}", $matches, PREG_PATTERN_ORDER);
var_dump($matches);
}
<?php
$matches = array();
$p = '/(mov|flv|youtube)/';
$replace_to = 'your text you want to be insted of the mov or flv or youtube';
$str = ' the string that you want to work on and replace its content';
$p_c = array(
$p => function($match) {
$ret = str_replace("mov", $replace_to, $match[0]);
$ret = str_replace("flv", $replace_to, $ret);
$ret = str_replace("youtube", $replace_to, $ret);
return $ret;
}
);
$res3 = preg_replace_callback_array($p_c, $str);
How can I process text with some codes.
So suppose I have text as below
Hello {::first_name::} {::last_name::},
How are you?
Your organisation is {::organisation::}
For any text between {:: and ::} should be evaluated to get its value.
I tried exploding text to array using space as delimiter and then parsing array items to look for "{::" and if found get string between "{::" and "::}" and calling database to get this field value.
So basically these will be db fields.
Below is the code I have tried
$msg = "Hello {::first_name::} {::last_name::},
How are you?
Your organisation is {::organisation::}";
$msg_array = explode(" ", $msg);
foreach ($msg_array as $str) {
if (strpos($str, "{::") !== false) {
$field_str = get_string_between($str, "{::", "::}");
$field_value = $bean->$field_str; //Logic that gets the value of the field
$msgStr .= $field_value . " ";
} else {
$msgStr .= $str . " ";
}
}
function get_string_between($string, $start, $end)
{
$string = ' ' . $string;
$ini = strpos($string, $start);
if ($ini == 0) return '';
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);
}
Your script seems fine. Your script in fiddle
If you are looking for alternative way, you can try using preg_match_all() with str_replace(array, array, source)
<?php
$bean = new stdClass();
$bean->first_name = 'John';
$bean->last_name = 'Doe';
$bean->organisation = 'PHP Company';
$string = "Hello {::first_name::} {::last_name::}, How are you? Your organisation is {::organisation::}";
// find all placeholders
preg_match_all('/{::(.+?)::}/i', $string, $matches);
$placeholders = $matches[0];
//strings inside placeholders
$parts = $matches[1];
// return values from $bean by matching object property with strings inside placeholders
$replacements = array_map(function($value) use ($bean) {
// use trim() to remove unexpected space
return $bean->{trim($value)};
}, $parts);
echo $newstring = str_replace($placeholders, $replacements, $string);
Short format:
$string = "Hello {::first_name::} {::last_name::}, How are you? Your organisation is {::organisation::}";
preg_match_all('/{::(.+?)::}/i', $string, $matches);
$replacements = array_map(function($value) use ($bean) {
return $bean->{trim($value)};
}, $matches[1]);
echo str_replace($matches[0], $replacements, $string);
And if you prefer to use a function:
function holder_replace($string, $source = null) {
if (is_object($source)) {
preg_match_all('/{::(.+?)::}/i', $string, $matches);
$replacements = array_map(function($value) use ($source) {
return (property_exists(trim($value), 'source')) ? $source->{trim($value)} : $value;
}, $matches[1]);
return str_replace($matches[0], $replacements, $string);
}
return $string;
};
echo holder_replace($string, $bean);
OUTPUT:
Hello John Doe, How are you? Your organisation is PHP Company
fiddle
Or you can simply use str_replace function:
$data = "{:: string ::}";
echo str_replace("::}", "",str_replace("{::", "", $data));
I am trying to replace this "iwdnowfreedom[body_style][var]" with this "iwdnowfreedom_body_style_var" in the name attributes of a variable. There could be several array keys but for my situation stripping them out shouldn't result in any issues.
Here is the code I have so far:
$pattern = '/name\\s*=\\s*["\'](.*?)["\']/i';
$replacement = 'name="$2"';
$fixedOutput = preg_replace($pattern, $replacement, $input);
return $fixedOutput;
How can I fix this to work properly?
You could try using the build in str_replace function to achieve what you are looking for (assuming there are no nested bracked like "test[test[key]]"):
$str = "iwdnowfreedom[body_style][var]";
echo trim( str_replace(array("][", "[", "]"), "_", $str), "_" );
or if you prefer regex (nested brackets work fine with this method):
$input = "iwdnowfreedom[body_style][var]";
$pattern = '/(\[+\]+|\]+\[+|\[+|\]+)/i';
$replacement = '_';
$fixedOutput = trim( preg_replace($pattern, $replacement, $input), "_" );
echo $fixedOutput;
I think you also meant that you might have a string such as
<input id="blah" name="test[hello]" />
and to parse the name attribute you could just do:
function parseNameAttribute($str)
{
$pos = strpos($str, 'name="');
if ($pos !== false)
{
$pos += 6; // move 6 characters forward to remove the 'name="' part
$endPos = strpos($str, '"', $pos); // find the next quote after the name="
if ($endPos !== false)
{
$name = substr($str, $pos, $endPos - $pos); // cut between name=" and the following "
return trim(preg_replace('/(\[+\]+|\]+\[+|\[+|\]+)/i', '_', $name), '_');
}
}
return "";
}
OR
function parseNameAttribute($str)
{
if (preg_match('/name="(.+?)"/', $str, $matches))
{
return trim(preg_replace('/(\[+\]+|\]+\[+|\[+|\]+)/i', '_', $matches[1]), '_');
}
return "";
}
I want to filter the input text if it's got A URL inside it.
By URL I mean that every thing that corresponds to a valid internet address like www.example.com, example.com, http://www.example.com, http://example.com/foo/bar.
I think I've gotta use regular expressions and the preg_match function so I need the correct regexp pattern for this purpose.
I'd be very grateful if anybody could give me that.
This article has a nice regex for matching urls: http://daringfireball.net/2010/07/improved_regex_for_matching_urls
For PHP you would need to escape the regex properly, for example like this:
$text = "here is some text that contains a link to www.example.com, and it will be matched.";
preg_match("/(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/", $text, $matches);
var_dump($matches);
$html = "http://www.scroogle.org
http://www.scroogle.org/
http://www.scroogle.org/index.html
http://www.scroogle.org/index.html?source=library
You can surf the internet anonymously at https://ssl.scroogle.org/cgi-bin/nbbwssl.cgi.";
preg_match_all('/\b((?P<protocol>https?|ftp):\/\/(?P<domain>[-A-Z0-9.]+)(?P<file>\/[-A-Z0-9+&##\/%=~_|!:,.;]*)?(?P<parameters>\?[A-Z0-9+&##\/%=~_|!:,.;]*)?)/i', $html, $urls, PREG_PATTERN_ORDER);
$urls = $urls[1][0];
Will match:
http://www.scroogle.org
http://www.scroogle.org/
http://www.scroogle.org/index.html
http://www.scroogle.org/index.html?source=library
You can surf the internet anonymously at https://ssl.scroogle.org/cgi-bin/nbbwssl.cgi.
To loop results you can use:
for ($i = 0; $i < count($urls[0]); $i++) {
echo $urls[1][$i]."\n";
}
will output:
http://www.scroogle.org
http://www.scroogle.org/
http://www.scroogle.org/index.html
http://www.scroogle.org/index.html?source=library
https://ssl.scroogle.org/cgi-bin/nbbwssl.cgi
cheers, Lob
Found here: http://zenverse.net/php-function-to-auto-convert-url-into-hyperlink/
Functions from WordPress.
function _make_url_clickable_cb($matches) {
$ret = '';
$url = $matches[2];
if ( empty($url) )
return $matches[0];
// removed trailing [.,;:] from URL
if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($url, -1);
$url = substr($url, 0, strlen($url)-1);
}
return $matches[1] . "$url" . $ret;
}
function _make_web_ftp_clickable_cb($matches) {
$ret = '';
$dest = $matches[2];
$dest = 'http://' . $dest;
if ( empty($dest) )
return $matches[0];
// removed trailing [,;:] from URL
if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($dest, -1);
$dest = substr($dest, 0, strlen($dest)-1);
}
return $matches[1] . "$dest" . $ret;
}
function _make_email_clickable_cb($matches) {
$email = $matches[2] . '#' . $matches[3];
return $matches[1] . "$email";
}
function make_clickable($ret) {
$ret = ' ' . $ret;
// in testing, using arrays here was found to be faster
$ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?#\[\]+]*)#is', '_make_url_clickable_cb', $ret);
$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?#\[\]+]*)#is', '_make_web_ftp_clickable_cb', $ret);
$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)#(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);
// this one is not in an array because we need it to run last, for cleanup of accidental links within links
$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
$ret = trim($ret);
return $ret;
}
Usage:
$string = 'I have some texts here and also links such as http://www.youtube.com , www.haha.com and lol#example.com. They are ready to be replaced.';
echo make_clickable($string);