String by string replacement - php

i got an array
$array = [
"a" => "c",
"b" => "d",
"c" => "a",
"d" => "b",
];
and a string $text = "dcab";
How can i replace with my array elements each letter on my string, im try to figure out by steps but not luck,
1.- explode my string
2.- for each letter str_replace,
output will be: bacd
thank for help.

Well you can't use str_replace() because of the big warning that it shows in the documentation:
Replacement order gotcha
Because str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements. See also the examples in this document.
Then take a look at the strtr() function
echo strtr($text, $array);

Related

Split a string at comma character but ignore if said character is nested inside parentheses

I'm currently working as a php dev, and now has an assignment with some old php legacy code that's intended to filter certain car details before adding it into the DB.
What I'm currently stuck on is how I'm supposed to skip splitting the models inside of the parenthesis
Example:
"v70, 790, v50 (v40, v44), v22"
Expected output:
[ "v70", "790", "v50 (v40, v44)", "v22" ]
So that the , inside of the parentheses is disregarded by the split.
Any help and pointers is greatly appreciated!
You can use preg_split() method for this (documentation). You can use this to split the string based on a regex pattern for comma separated values but ignored if these are between parentheses.
This code works for your example:
<?php
$string = 'v70, 790, v50 (v40, v44), v22';
$pattern = '/,(?![^(]*\)) /';
$splitString = preg_split($pattern, $string);
Output of $splitString looks like:
array (size=4)
0 => string 'v70' (length=3)
1 => string '790' (length=3)
2 => string 'v50 (v40, v44)' (length=14)
3 => string 'v22' (length=3)

Stop regex splitting a matched url with preg_split

Given the following code:
$regex = '/(http\:\/\/|https\:\/\/)([a-z0-9-\.\/\?\=\+_]*)/i';
$text = preg_split($regex, $note, -1, PREG_SPLIT_DELIM_CAPTURE);
its returning an array such as:
array (size=4)
0 => string '...' (length=X)
1 => string 'https://' (length=8)
2 => string 'duckduckgo.com/?q=how+much+wood+could+a+wood-chuck+chuck+if+a+wood-chuck+could+chuck+wood' (length=89)
3 => string '...' (length=X)
I would prefer it if the returned array had size=3, with one single URL. Is this possible?
Sure that can be done, just remove those extra matching groups from your regex. Try following code:
$regex = '#(https?://[a-z0-9.?=+_-]*)#i';
$text = preg_split($regex, $note, -1, PREG_SPLIT_DELIM_CAPTURE);
Now resulting array will have 3 elements in the array instead of 4.
Besides removing extra grouping I have also simplified your regex also since most of the special characters don't need to be escaped inside character class.

Parse string of alternating letters and numbers (no delimiters) to associative array

I need to parse a string of alternating letters and number and populate an array where the letters are the keys and the numbers are the values.
Example:
p10s2z1234
Output
Array(
'p' => 10,
's' => 2,
'z' => 1234
)
Use regex to get desired values and then combine arrays to get associative array. For example:
$str = 'p10s2z1234';
preg_match_all('/([a-z]+)(\d+)/', $str, $matches); //handles only lower case chars. feel free to extend regex
print_r(array_combine($matches[1], $matches[2]));
Scenario 1: You want to parse the string which has single letters to be keys, will produce three pairs of values, and you want the digits to be cast as integers. Then the best, most direct approach is sscanf() with array destructuring -- a single function call does it all. (Demo)
$str = 'p10s2z1234';
[
$k1,
$result[$k1],
$k2,
$result[$k2],
$k3,
$result[$k3]
] = sscanf($str, '%1s%d%1s%d%1s%d');
var_export($result);
Output:
array (
'p' => 10,
's' => 2,
'z' => 1234,
)
Scenario 2: You want the same parsing and output as scenario 1, but the substrings to be keys have variable/unknown length. (Demo)
$str = 'pie10sky2zebra1234';
[
$k1,
$result[$k1],
$k2,
$result[$k2],
$k3,
$result[$k3]
] = sscanf($str, '%[^0-9]%d%[^0-9]%d%[^0-9]%d');
var_export($result);
Scenario 3: You want to parse the string with regex and don't care that the values are "string" data-typed. (Demo)
$str = 'pie10sky2zebra1234';
[
$k1,
$result[$k1],
$k2,
$result[$k2],
$k3,
$result[$k3]
] = preg_split('/(\d+)/', $str, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
var_export($result);
Scenario 4: If you don't know how many pairs will be generated by the input string, use array_combine(). (Demo)
$str = 'pie10sky2zebra1234extra999';
var_export(
preg_match_all('/(\D+)(\d+)/', $str, $m)
? array_combine($m[1], $m[2])
: []
);

PHP: preg_match and group repetition

How I can get all matched objects in a group using preg_match (or preg_match_all, maybe)?
For instance, I have ^(?:,?\s*(?<key>[a-z]))+$, if I apply to a, b, c, I get this:
object array
0 : string "a, b, c"
key: string "c"
1 : string "c"
I need basically of get a, b and c. Something like it (don't needly like it):
object array
0 : string "a, b, c"
key: object array
0 : string "a"
1 : string "b"
2 : string "c"
...
It's possible? What is the better solution? I need really to split it after match?
Split it on ,\s*, eg:
$array = preg_split("/,\\s*/", "a, b, c,d,e");
No you can not nest it like that. You can build the array manually however.
$str = 'a, b, c';
preg_match_all("/(\w),?/", $str, $m);
// create array
$a = array(
$str,
'key' => $m[1]
);
print_r($a);
You can use preg_split too go grab this elements.
$m = preg_split('/\W+/', $str, PREG_SPLIT_NO_EMPTY);

Convert Regexp in Js into PHP?

I have the following regular expression in javascript and i would like to have the exact same functionality (or similar) in php:
// -=> REGEXP - match "x bed" , "x or y bed":
var subject = query;
var myregexp1 = /(\d+) bed|(\d+) or (\d+) bed/img;
var match = myregexp1.exec(subject);
while (match != null){
if (match[1]) { "X => " + match[1]; }
else{ "X => " + match[2] + " AND Y => " + match[3]}
match = myregexp1.exec(subject);
}
This code searches a string for a pattern matching "x beds" or "x or y beds".
When a match is located, variable x and variable y are required for further processing.
QUESTION:
How do you construct this code snippet in php?
Any assistance appreciated guys...
You can use the regex unchanged. The PCRE syntax supports everything that Javascript does. Except the /g flag which isn't used in PHP. Instead you have preg_match_all which returns an array of results:
preg_match_all('/(\d+) bed|(\d+) or (\d+) bed/im', $subject, $matches,
PREG_SET_ORDER);
foreach ($matches as $match) {
PREG_SET_ORDER is the other trick here, and will keep the $match array similar to how you'd get it in Javascript.
I've found RosettaCode to be useful when answering these kinds of questions.
It shows how to do the same thing in various languages. Regex is just one example; they also have file io, sorting, all kinds of basic stuff.
You can use preg_match_all( $pattern, $subject, &$matches, $flags, $offset ), to run a regular expression over a string and then store all the matches to an array.
After running the regexp, all the matches can be found in the array you passed as third argument. You can then iterate trough these matches using foreach.
Without setting $flags, your array will have a structure like this:
$array[0] => array ( // An array of all strings that matched (e.g. "5 beds" or "8 or 9 beds" )
0 => "5 beds",
1 => "8 or 9 beds"
);
$array[1] => array ( // An array containing all the values between brackets (e.g. "8", or "9" )
0 => "5",
1 => "8",
2 => "9"
);
This behaviour isn't exactly the same, and I personally don't like it that much. To change the behaviour to a more "JavaScript-like"-one, set $flags to PREG_SET_ORDER. Your array will now have the same structure as in JavaScript.
$array[0] => array(
0 => "5 beds", // the full match
1 => "5", // the first value between brackets
);
$array[1] => array(
0 => "8 or 9 beds",
1 => "8",
2 => "9"
);

Categories