Lets say I have a string "My name is $name and my pet is $animal"
How to check if string has variables inside it? And if has, add to array like
$array = ("$name","animal");
Would it be some pregmatch? but then all $+sometextafterthesymbol needs to be extracted and $ with space after it left alone.
Any ideas?
You can use regular expressions for this. The following will match any dollar sign followed by 1 or more word characters (letters, numbers, or underscore):
preg_match_all('/\$(\w+)/', $string, $matches);
$matches:
Array
(
[0] => Array
(
[0] => $name
[1] => $animal
)
[1] => Array
(
[0] => name
[1] => animal
)
)
Remember that $string, if hardcoded, must be wrapped in single quotes (').
Related
I am running some simple code from http://www.writephponline.com/
Inputs
$str = "$Q$14";
$arr = explode("$", $str);
print_r($arr);
Outputs
Array ( [0] => [1] => 14 )
My question is why array at index 0 is empty, shouldn't that be letter Q?
Please check the photo
The main problem is the choice of the double quoted string type:
$Q = '$Q';
print_r(explode('$', "$Q$14"));
Array ( [0] => [1] => Q [2] => 14 )
So what is happening in your code is a "double quoted" string replaces valid variable names to the value of them, where $Q is a valid name and $14 is not because they may not start with a digit.
echo "$Q$14";
Notice: Undefined variable: Q in ... on line ...
$14
So you're actually concatenating null . '$14' as variable $Q does not exist in your code and that value is null so the end value is: $14
If you would use a 'literal' string, it works as expected:
echo '$Q$14';
$Q$14
The other thing is that explode() splits the string into 2 pieces from the first delimiter found, so you will have a left and a right part. Any traditional delimiter found only causes 1 index to be appended. The string starts with a delimiter so the first array index is expected to be null because no value exists left of the first character.
print_r(explode('.', 'left.right'));
print_r(explode('.', 'left.middle.right'));
print_r(explode('$', '$Q$14'));
Array ( [0] => left [1] => right )
Array ( [0] => left [1] => middle [2] => right )
Array ( [0] => [1] => Q [2] => 14 )
If you really want to achieve desired output with the same string you specified then try this one, add backslash(\) before first $
$str = "\$Q$14";
$arr = explode("$", $str);
print_r($arr);
I tried it and it worked.
I need a help to parse the characters inside those brackets:
[]
{}
<>
{|}
<|>
For example, I have this string variable (Japanese):
$question = "この<部屋|へや>[に]{椅子|いす}[が]ありません";
Expected result in HTML:
Description
1) This is a particle. I will convert all word inside [] into HTML tag. Example: [に] will be converted into <span style="color:blue">に</span>. A full sentence can have multiple []. Note: I understand how to use str_replace.
2 and 4) This is normal kanji word which will be used as a question to the user. A full sentence can only have one {}.
3 and 5) This is normal kanji text. A full sentence can have multiple {}.
2, 3, 4, and 5) They will converted into Ruby html tags. Sometimes they will not have a | separator, which is not mandatory. From what I understand, I just need to explode the | characters. If explode return false or | not exist, I will use original value. Note: I understand how to use ruby tags (rb and rt).
My question
How do I parse characters 1-5 I mentioned above with PHP? What keyword I need to start?
Thanks.
Thanks to this page: Capturing text between square brackets in PHP, now I have my own answer.
Full code:
<?php
$text = "この<部屋|へや>[に]{椅子|いす}[が]ありません";
preg_match_all("/\[([^\]]*)\]/", $text, $square_brackets); //[]
preg_match_all("/{([^}]*)}/", $text, $curly_brackets); //{}
preg_match_all("/<([^}]*)>/", $text, $angle_brackets); //<>
print_r($square_brackets);
echo "\r\n";
print_r($curly_brackets);
echo "\r\n";
print_r($angle_brackets);
echo "\r\n";
Result:
Array
(
[0] => Array
(
[0] => [に]
[1] => [が]
)
[1] => Array
(
[0] => に
[1] => が
)
)
Array
(
[0] => Array
(
[0] => {椅子|いす}
)
[1] => Array
(
[0] => 椅子|いす
)
)
Array
(
[0] => Array
(
[0] => <部屋|へや>
)
[1] => Array
(
[0] => 部屋|へや
)
)
Thanks.
I've had a good look around for a question that asked this before; alas, my search for a PHP preg_match search returned no results (maybe my searching skills fell short, I suppose justified considering it's a Regex question!).
Consider the text below:
The quick __("brown ") fox jumps __('over the') lazy __("dog")
Now currently I need to 'scan' for the given method __('') above, whereas it could include the spacing and different quotations ('|"). My best attempt after numerous 'iterations':
(__\("(.*?)"\))|(__\('(.*?)'\))
Or at its simplest form:
__\((.*?)\)
To break this down:
Anything that starts with __
Escaped ( and quotation mark " or '. Thus, \(\"
(.*?) Non-greedy match of all characters
Escaped closing " and last bracket.
| between the two expressions match either/or.
However, this only gets partial matches, and spaces are throwing off the search entirely. Apologies if this has been asked before, please link me if so!
Tester Link for the pattern provided above:
PHP Live Regex Test Tool
When the searched method string uses single quotes it will end up in another capture group than if it has double quotes. So in fact, your regular expression works (except for the spaces, see further down), but you'd have to look at a different index in your result array:
$input = 'The quick __("brown ") fox jumps __(\'over the\') lazy __("dog")';
// using your regular expression:
$res = preg_match_all("/(__\(\"(.*?)\"\))|(__\('(.*?)'\))/", $input, $matches);
print_r ($matches);
Note that you need preg_match_all instead of preg_match to get all matches.
Output:
Array
(
[0] => Array
(
[0] => __("brown ")
[1] => __('over the')
[2] => __("dog")
)
[1] => Array
(
[0] => __("brown ")
[1] =>
[2] => __("dog")
)
[2] => Array
(
[0] => brown
[1] =>
[2] => dog
)
[3] => Array
(
[0] =>
[1] => __('over the')
[2] =>
)
[4] => Array
(
[0] =>
[1] => over the
[2] =>
)
)
So, the result array has 5 elements, the first one representing the complete match, and all the others correspond to the 4 capture groups you have in your regular expression. As the capture groups for single quotes are not those of the double quotes, you'll find the matches at different places.
To "solve" this, you could use a back reference in your regular expression, which would look back to see which was the opening quote (single or double) and require the same to be repeated at the end:
$res = preg_match_all("/__\(([\"'])(.*?)\\1\)/", $input, $matches);
Note the back reference \1 (the backslash had to be escaped with another one). This refers back to the first capture group, where we have ["'] (again an escape was necessary) to match both kinds of quotes.
You also wanted to deal with spaces. On your PHP Live Regex you used a test string that had such spaces between the brackets and quotes. To deal with these so they still match the method strings correctly, the regular expression should get two additional \s*:
$res = preg_match_all("/__\(\s*([\"'])(.*?)\\1\s*\)/", $input, $matches);
Now the output is:
Array
(
[0] => Array
(
[0] => __("brown ")
[1] => __('over the')
[2] => __("dog")
)
[1] => Array
(
[0] => "
[1] => '
[2] => "
)
[2] => Array
(
[0] => brown
[1] => over the
[2] => dog
)
)
... and the text captured by the groups is now nicely arranged.
See this code run on eval.in and PHP Live Regex.
When working with stuff like this, don't forget about escaping:
<?php
ob_start();
?>
The quick __("brown ") fox jumps __( 'over the' ) lazy __("dog").
And __("everyone says \"hi\"").
<?php
$content = ob_get_clean();
$re = <<<RE
/__ \(
\s*
" ( (?: \\\\. | [^"])+ ) "
|
' ( (?: \\\\. | [^'])+ ) '
\s*
\)
/x
RE;
preg_match_all($re, $content, $matches, PREG_SET_ORDER);
foreach($matches as $match)
echo end($match), "\n";
How about this:
(__(\('[^']+'\)|\("[^"]+"\)))
Instead of the non greedy ., use any char but the quotes [^'] or [^"]
Enclose double and single quotes with square brackets as a character class:
$str = 'The quick __( "brown ") fox jumps __(\'over the\') lazy __("dog")';
preg_match_all("/__\(\s*([\"']).*?\\1\s*\)/ium", $str, $matches);
echo '<pre>';
var_dump($matches[0]);
// the output:
array (size=3)
0 => string '__( "brown ")'
1 => string '__('over the')'
2 => string '__("dog")'
And here is example with the same solution on phpliveregex.com:
http://www.phpliveregex.com/p/exF
(section preg_match_all)
Im trying to split string in PHP. I should split string using two delimiters: new line and comma. My code is:
$array = preg_split("/\n|,/", $str)
But i get string split using comma, but not using \n. Why is that? Also , do I have to take into account "\r\n" symbol?
I can think of two possible reasons that this is happening.
1. You are using a single quoted string:
$array = preg_split("/\n|,/", 'foo,bar\nbaz');
print_r($array);
Array
(
[0] => foo
[1] => bar\nbaz
)
If so, use double quotes " instead ...
$array = preg_split("/\n|,/", "foo,bar\nbaz");
print_r($array);
Array
(
[0] => foo
[1] => bar
[2] => baz
)
2. You have multiple newline sequences and I would recommend using \R if so. This matches any Unicode newline sequence that is in the ASCII range.
$array = preg_split('/\R|,/', "foo,bar\nbaz\r\nquz");
print_r($array);
Array
(
[0] => foo
[1] => bar
[2] => baz
[3] => quz
)
I have a string like that :
0d(Hi)i(Hello)4d(who)i(where)540d(begin)i(began)
And i want to make it an array with that.
I try first to add separator, in order to use the php function explode.
;0,d(Hi),i(Hello);4,d(who),i(where);540,d(begin),i(began)
It works but the problem is I want to minimize the separator to save disk space.
Therefore i want to know by using preg_split, regular expression, if it's possible to have a huge array like that without using separator :
Array ( [0] => Array ( [0] => 0 [1] => d(hi) [2] => i(Hello) )
[1] => Array ( [0] => 4 [1] => d(who) [2] => i(where) )
[2] => Array ( [0] => 540 [1] => d(begin) [2] => i(began) )
)
I try some code & regex, but I saw that the value in the regular expression was not present in the final result (like explode function, in the final array we do not have the delimitor.)
More over, i have some difficulties to build the regex. Here is the one that I made :
$modif = preg_split("/[0-9]+(d(.+))?(i(.+))?/", $data);
I must precise that d() and i() can not be present (but at least one)
Thanks
If you do
preg_match_all('/(\d+)(d\([^()]*\))?(i\([^()]*\))?/', $subject, $result, PREG_SET_ORDER);
on your original string, then you'll get an array where
$result[$i][0]
contains the ith match (i. e. $result[0][0] would be 0d(Hi)i(Hello)) and where
$result[$i][$c]
contains the cth capturing group of the ith match (i. e. $result[0][1] is 0, $result[0][2] is d(Hi) and $result[0][2] is i(Hello)).
Is that what you wanted?