Replace a string with a result from MySQL - php

How would I replace a string like: {snippet:1} with a MySQL result that uses the number (in this case 1) to select the row from a table that has 1 as its ID?
Thanks

I would use a regex for to separate out the integer from your string.
$string = '{snippet:1}';
preg_match('/\{snippet:(\d+)\}/', $string, $match);
echo $match[1];
Output:
1
The /s are delimiters telling where the regex starts and ends. The \d is any number and the + is a quantifier telling it that there can be one or more numbers. The \s are making the {}s literal.
Regex101 Demo: https://regex101.com/r/cB9oN1/1
If this were JSON though...
$string = '{"snippet":"1"}';
$json_value = json_decode($string);
echo $json_value->snippet;
Output:
1

Related

Avoid backreference replacement in php's preg_replace

Consider the below use of preg_replace
$str='{{description}}';
$repValue='$0.0 $00.00 $000.000 $1.1 $11.11 $111.111';
$field = 'description';
$pattern = '/{{'.$field.'}}/';
$str =preg_replace($pattern, $repValue, $str );
echo $str;
// Expected output: $0.0 $00.00 $000.000 $1.1 $11.11 $111.11
// Actual output: {{description}}.0 {{description}}.00 {{description}}0.000 .1 .11 1.111
Here is a phpFiddle showing the issue
It's clear to me that the actual output is not as expected because preg_replace is viewing $0, $0, $0, $1, $11, and $11 as back references for matched groups replacing $0 with the full match and $1 and $11 with an empty string since there are no capture groups 1 or 11.
How can I prevent preg_replace from treating prices in my replacement value as back references and attempting to fill them?
Note that $repValue is dynamic and it's content will not be know before the operation.
Escape the dollar character before using a character translation (strtr):
$repValue = strtr('$0.0 $00.00 $000.000 $1.1 $11.11 $111.111', ['$'=>'\$']);
For more complicated cases (with dollars and escaped dollars) you can do this kind of substitution (totally waterproof this time):
$str = strtr($str, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']);
$repValue = strtr($repValue, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']);
$pattern = '/{{' . strtr($field, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']) . '}}/';
$str = preg_replace($pattern, $repValue, $str );
echo strtr($str, ['%%'=>'%', '$%'=>'$', '\\%'=>'\\']);
Note: if $field contains only a literal string (not a subpattern), you don't need to use preg_replace. You can use str_replace instead and in this case you don't have to substitute anything.

Add + before word, see all between quotes as one word

I have a question. I need to add a + before every word and see all between quotes as one word.
A have this code
preg_replace("/\w+/", '+\0', $string);
which results in this
+test +demo "+bla +bla2"
But I need
+test +demo +"bla bla2"
Can someone help me :)
And is it possible to not add a + if there is already one? So you don't get ++test
Thanks!
Maybe you can use this regex:
$string = '+test demo between "double quotes" and between \'single quotes\' test';
$result = preg_replace('/\b(?<!\+)\w+|["|\'].+?["|\']/', '+$0', $string);
var_dump($result);
// which will result in:
string '+test +demo +between +"double quotes" +and +between +'single quotes' +test' (length=74)
I've used a 'negative lookbehind' to check for the '+'.
Regex lookahead, lookbehind and atomic groups
I can't test this but could you try it and let me know how it goes?
First the regex: choose from either, a series of letters which may or may not be preceded by a '+', or, a quotation, followed by any number of letters or spaces, which may be preceded by a '+' followed by a quotation.
I would hope this matches all your examples.
We then get all the matches of the regex in your string, store them in the variable "$matches" which is an array. We then loop through this array testing if there is a '+' as the first character. If there is, do nothing, otherwise add one.
We then implode the array into a string, separating the elements by a space.
Note: I believe $matches in created when given as a parameter to preg_match.
$regex = '/[((\+)?[a-zA-z]+)(\"(\+)?[a-zA-Z ]+\")]/';
preg_match($regex, $string, $matches);
foreach($matches as $match)
{
if(substr($match, 0, 1) != "+") $match = "+" + $match;
}
$result = implode($matches, " ");

Cutting string by first number found

I have to cut the first part of my string before any number found. For example:
string: "BOBOSZ 27A lok.6" should be cutted to 'BOBOSZ "
string: "aaa 43543" should be cutted to "aaa "
string: "aa2bhs2" should be cutted to "aa"
Im trying with preg_split and explode funcionts but i can't get the right result for now.
Thanks in advance !
You can use this pattern with the preg_match() function:
preg_match('/^[^0-9]+/', $str, $match);
print_r($match);
pattern details:
^ # anchor: start of the string
[^0-9]+ # negated character class: all that is not a digit one or more times
note: you can replace + by * if you consider that an empty string is a valid result.
If you absolutly want to use the preg_split() function, you do:
$result = preg_split('/(?=(?:[^0-9].*)?$)/s', $str);
echo $result[0];
preg_match('#(\w+)\s?\d+#', $string, $match);
You should get $match[1] as I remember :)

Trim all characters before an integer in a string in PHP?

I have an alpha numeric string say for example,
abc123bcd , bdfnd567, dfd89ds.
I want to trim all the characters before the first appearance of any integer in the string.
My result should look like,
abc , bdfnd, dfd.
I am thinking of using substr. But not sure how to check for a string before first appearance of an integer.
You can easily remove the characters you don't want with preg_replace [docs] and a regular expression:
$str = preg_replace('#\d.*$#', '', $str);
\d matches a digit and .*$ matches any character until the end of the string.
Learn more about regular expressions: http://www.regular-expressions.info/.
DEMO
A possible non-Regex solution would be:
strcspn — Find length of initial segment not matching mask
substr — Return part of a string
Example:
$string = 'foo1bar';
echo substr($string, 0, strcspn($string, '1234567890')); // gives foo
$string = 'abc123bcd';
preg_replace("/[0-9]/", "", $string);
or
trim($string, '0123456789');
I believe you are looking for this?
$matches = array();
preg_match("/^[a-z]+/", "dfd89ds", $matches);
echo $matches[0]; // returns dfd
You can use a regex for this:
$string = 'abc123bcd';
preg_match('/^[a-zA-Z]*/i', $string, $matches);
var_dump($matches[0]);
will produce:
abc
To remove the +/- sign, you can simply use:
abs($number)
and get the absolute value.
e.g
$abs = abs($signed_integer);

Get integer value from malformed query string

I'm looking for an way to parse a substring using PHP, and have come across preg_match however I can't seem to work out the rule that I need.
I am parsing a web page and need to grab a numeric value from the string, the string is like this
producturl.php?id=736375493?=tm
I need to be able to obtain this part of the string:
736375493
$matches = array();
preg_match('/id=([0-9]+)\?/', $url, $matches);
This is safe for if the format changes. slandau's answer won't work if you ever have any other numbers in the URL.
php.net/preg-match
<?php
$string = "producturl.php?id=736375493?=tm";
preg_match('~id=(\d+)~', $string, $m );
var_dump($m[1]); // $m[1] is your string
?>
$string = "producturl.php?id=736375493?=tm";
$number = preg_replace("/[^0-9]/", '', $string);
Unfortunately, you have a malformed url query string, so a regex technique is most appropriate. See what I mean.
There is no need for capture groups. Just match id= then forget those characters with \K, then isolate the following one or more digital characters.
Code (Demo)
$str = 'producturl.php?id=736375493?=tm';
echo preg_match('~id=\K\d+~', $str, $out) ? $out[0] : 'no match';
Output:
736375493
For completeness, there 8s another way to scan the formatted string and explicitly return an int-typed value. (Demo)
var_dump(
sscanf($str, '%*[^?]?id=%d')[0]
);
The %*[^?] means: greedily match one or more non-question mark characters, but do not capture the substring. The remainder of the format parameter matches the literal sequence ?id=, then greedily captures one or more numbers. The returned value will be cast as an integer because of the %d placeholder.

Categories