Remove elements from an array that do not match a regex - php

In PHP, is there a function or anything else that will remove all elements in an array that do not match a regex.
My regex is this: preg_match('/^[a-z0-9\-]+$/i', $str)
My array's come in like this, from a form (they're tags actually)
Original array from form. Note: evil tags
$arr = array (
"french-cuisine",
"french-fries",
"snack-food",
"evil*tag!!",
"fast-food",
"more~evil*tags"
);
Cleaned array. Note, no evil tags
Array (
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[3] => fast-food
)
I currently do like this, but is there a better way? Without the loop maybe?
foreach($arr as $key => $value) {
if(!preg_match('/^[a-z0-9\-]+$/i', $value)) {
unset($arr[$key]);
}
}
print_r($arr);

You could use preg_grep() to filter the array entries that match the regular expression.
$cleaned = preg_grep('/^[a-z0-9-]+$/i', $arr);
print_r($cleaned);
Output
Array
(
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[4] => fast-food
)

I would not necessarily say it's any better per se, but using regexp and array_filter could look something like this:
$data = array_filter($arr , function ($item){
return preg_match('/^[a-z0-9\-]+$/i', $item);
});
Where we're returning the result of the preg_match which is either true/false. In this case, it should correctly remove the matched evil tags.
Here's your eval.in

Related

Check if array key matches data from select query

I have a multidimensional array. They keys of the separate arrays are text. I would like to know how to match the key with part of a string that's from looped SELECT data.
Example of Array
Array ( [Volvo] => Array ( [0] => )
[Ford] => Array ( [0] => )
[Seat] => Array ( [0] => ) )
So from this array $cars, how would I be able to match data coming from my SELECT query
Select Output echo $row['car'];
Volvo, Mercedes, Lexus
What I'm after
if the key of one of my arrays matches part of the string from my select query, so as the example says above Volvo would match, then do something. That something for me is adding more data in that array.
I have tried variations of in_array, array_search and array_filter but have not found a solution that works for me.
Example of the reverse of what i was doing through a foreach loop
$searchword = $array_element;
$result = array_filter($cars, function($var) use ($searchword) { return preg_match("/\b$searchword\b/i", $var); });
taken from: Search for PHP array element containing string
This should work for you:
First I used preg_split() to split your search string (Volvo, Mercedes, Lexus) into an array.
The regex:
/\s*,\s*/
Simply means this:
\s* match any white space character [\r\n\t\f ]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
, matches the character , literally
\s* match any white space character [\r\n\t\f ]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
This makes sure we don't have spaces in the search words from your string. So with this we will end up with an array like this:
Array
(
[0] => Volvo
[1] => Mercedes
[2] => Lexus
)
After that I just take the array_intersect_key() from your array and the search array, which we just created.
Code:
<?php
$arr = preg_split("/\s*,\s*/", $row["car"], -1, PREG_SPLIT_NO_EMPTY);
if(($intersect = array_intersect_key($cars, array_flip($arr)))) {
echo "Do stuff!";
print_r($intersect);
} else {
echo "Drink a cup of tea";
}
?>
output:
Array
(
[Volvo] => Array
(
[0] =>
)
)
There are many ways to achieve your goal. I would use function explode() to split the data retrieved from the database ($row['car']) into pieces and trim() to be sure the identified pieces do not have padding spaces:
$brands = array_map('trim', explode(',', $row['car']));
Now, print_r($brands) should reveal an array whose values are candidate keys in your example array (called $example below).
Next it depends on what you want to match and how you want to process the matches.
A simple identification can be done using array_intersect() with $brands and the keys of the example array (see function array_keys()).
$common = array_intersect($brands, array_keys($example));
foreach ($common as $key) {
// Do something with $example[$key]
}
Or you can iterate directly over $brands and check if the value is a key in $example:
foreach ($brands as $key) {
if (array_key_exists($key, $example)) {
// Do something with $example[$key]
}
}
You can use isset($example[$key]) as well, instead of array_key_exists($key, $example]).
Try using PHP stripos, it's simple and effective:
Base data:
$array = Array ( [Volvo] => Array ( [0] => )
[Ford] => Array ( [0] => )
[Seat] => Array ( [0] => ) )
;
SQL data (string or array):
$row['car']; // string
$row //array of all SQL columns output
Foreach with stripos:
foreach($array as $rowKey=>$rowArray){
$rowKey = trim($rowKey);
foreach($row as $sqlRow=>$sqlArray){
$sqlRow = trim($sqlRow);
if (stripos($rowKey,$sqlRow) !== false){
///values are the same in this key in the array and in the SQL output
}
}
unset($sqlRow,$sqlArray);
}
unset($rowKey,$rowArray);
This may not be the most efficient but should give you the result you want

PHP from string to multiple arrays at the hand of placeholders

Good day,
I have an I think rather odd question and I also do not really know how to ask this question.
I want to create a string variable that looks like this:
[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]
This should be processed and look like:
$variable = array(
'car' => array(
'Ford',
'Dodge',
'Chevrolet',
'Corvette'
),
'motorcycle' => array(
'Yamaha',
'Ducati',
'Gilera',
'Kawasaki'
)
);
Does anyone know how to do this?
And what is it called what I am trying to do?
I want to explode the string into the two arrays. If it is a sub array
or two individual arrays. I do not care. I can always combine the
latter if I wish so.
But from the above mentioned string to two arrays. That is what I
want.
Solution by Dlporter98
<?php
///######## GET THE STRING FILE OR DIRECT INPUT
// $str = file_get_contents('file.txt');
$str = '[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]';
$str = explode(PHP_EOL, $str);
$finalArray = [];
foreach($str as $item){
//Use preg_match to capture the pieces of the string we want using a regular expression.
//The first capture will grab the text of the tag itself.
//The second capture will grab the text between the opening and closing tag.
//The resulting captures are placed into the matches array.
preg_match("/\[(.*?)\](.*?)\[/", $item, $matches);
//Build the final array structure.
$finalArray[$matches[1]][] = $matches[2];
}
print_r($finalArray);
?>
This gives me the following array:
Array
(
[car] => Array
(
[0] => Ford
[1] => Dodge
[2] => Chevrolet
[3] => Corvette
)
[motorcycle] => Array
(
[0] => Yamaha
[1] => Ducati
[2] => Gilera
[3] => Kawasaki
)
)
The small change I had to make was:
Change
$finalArray[$matches[1]] = $matches[2]
To:
$finalArray[$matches[1]][] = $matches[2];
Thanks a million!!
There are many ways to convert the information in this string to an associative array.
split the string on the new line into an array using the explode function:
$str = "[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]";
$items = explode(PHP_EOL, $str);
At this point each delimited item is now an array entry.
Array
(
[0] => [car]Ford[/car]
[1] => [car]Dodge[/car]
[2] => [car]Chevrolet[/car]
[3] => [car]Corvette[/car]
[4] => [motorcycle]Yamaha[/motorcycle]
[5] => [motorcycle]Ducati[/motorcycle]
[6] => [motorcycle]Gilera[/motorcycle]
[7] => [motorcycle]Kawasaki[/motorcycle]
)
Next, loop over the array and pull out the appropriate pieces needed to build the final associative array using the preg_match function with a regular expression:
$finalArray = [];
foreach($items as $item)
{
//Use preg_match to capture the pieces of the string we want using a regular expression.
//The first capture will grab the text of the tag itself.
//The second capture will grab the text between the opening and closing tag.
//The resulting captures are placed into the matches array.
preg_match("/\[(.*?)\](.*?)\[/", $item, $matches);
//Build the final array structure.
$finalArray[$matches[1]] = $matches[2]
}
The following is an example of what will be found in the matches array for a given iteration of the foreach loop.
Array
(
[0] => [motorcycle]Gilera[
[1] => motorcycle
[2] => Gilera
)
Please note that I use the PHP_EOL constant to explode the initial string. This may not work if the string was pulled from a different operating system than the one you are running this code on. You may need to replace this with the actual end of line characters that is being used by the string.
Why don't you create two separate arrays?
$cars = array("Ford", "Dodge", "Chevrolet", "Corvette");
$motorcycle = array("Yamaha", "Ducati", "Gilera", "Kawasaki");
You could also use an Associative array to do this.
$variable = array("Ford"=>"car", "Yamaha"=>"motorbike");

PHP ARRAY_PUSH strips html tag

I have a string which i am trying to split and then add a span tag on every 2 words.
When I split the string and try to use array_push to create a new array, my html tags disappears.
Here is my function:
public function splitString(){
$string = Sample sentence;
$newHeader = array();
$parts = preg_split('/\s+/', $string);
$num = 1;
foreach($parts as $str){
if($num % 2 == 0){
array_push($newHeader, "<span>".$str."</span>");
}else{
array_push($newHeader, $str);
}
$num++;
}
return $newHeader;
}
When I call that function the result i get is
Array ( [0] => Sample [1] => sentence )
I am looking for:
Array ( [0] => Sample [1] => <span>sentence</span> )
What I am doing wrong? Please help
Thank you in advance
First, if you haven't corrected, just like #Fred said in the comments, you should quote your strings in that function:
$string = 'Sample sentence';
Second, it works. array_push() does not strip your tags. You are just presented with a print_r() on the browser but its there along with the word.
Array ( [0] => Sample [1] => sentence )
If look at it in the view source. This is what it looks like:
print_r(splitString());
Array
(
[0] => Sample
[1] => <span>sentence</span>
)
You just don't see it visually on the browser but the tags are there.
If you try to add this up:
array_push($newHeader, "<span style='color: red;'>".$str."</span>");
You'll see the style. Try it :)

PHP - What regex code do I need to match this boundary sequence?

I have the following text string:
-asc100-17-asc100-17A-asc100-17BPH-asc100-17ASL
What regex code do I need to extract the values so that they appear in the matches array like this:
-asc100-17
-asc100-17A
-asc100-17BPH
-asc100-17ASL
Thanks in advance!
You may try this:
$str = "-asc100-17-asc100-17A-asc100-17BPH-asc100-17ASL";
preg_match_all('/-asc\d+-[0-9a-zA-Z]+/', $str, $matches);
// Print Result
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => -asc100-17
[1] => -asc100-17A
[2] => -asc100-17BPH
[3] => -asc100-17ASL
)
)
Based on the very limited information in your question, this works:
-asc100-17[A-Z]*
Debuggex Demo
If you want to capture the post -asc100- code, then use
-asc100-(17[A-Z]*)
Which places 17[the letters] into capture group one.
Might use preg_split with a lookahead as well for your scenario:
print_r(preg_split('/(?=-asc)/', $str, -1, PREG_SPLIT_NO_EMPTY));
Are you trying to break the string in an array? Then why regex is required? This function can handle what you want:
$arr = explode('-asc', '-asc100-17-asc100-17A-asc100-17BPH-asc100-17ASL');
foreach ($arr as $value) {
if(!empty($value)){
$final[] = '-asc'.$value;
}
}
print_r($final);
Output array : Array ( [0] => -asc100-17 [1] => -asc100-17A [2] => -asc100-17BPH [3] => -asc100-17ASL )

str_replace in array, and append text at the end

So I'm kind of stuck on this - I'm looking to replace text in an array (easily done via str_replace), but I would also like to append text onto the end of that specific array. For example, my original array is:
Array
(
[1] => DTSTART;VALUE=DATE:20130712
[2] => DTEND;VALUE=DATE:20130713
[3] => SUMMARY:Vern
[4] => UID:1fb5aa60-ff89-429e-80fd-ad157dc777b8
[5] => LAST-MODIFIED:20130711T010042Z
[6] => SEQUENCE:1374767972
)
I would like to search that array for ";VALUE=DATE" and replace it with nothing (""), but would also like to insert a text string 7 characters after each replace ("T000000"). So my resulting array would be:
Array
(
[1] => DTSTART:20130712T000000
[2] => DTEND:20130713T000000
[3] => SUMMARY:Vern
[4] => UID:1fb5aa60-ff89-429e-80fd-ad157dc777b8
[5] => LAST-MODIFIED:20130711T010042Z
[6] => SEQUENCE:1374767972
)
Is something like this possible using combinations of str_replace, substr_replace, etc? I'm fairly new to PHP and would love if someone could point me in the right direction! Thanks much
You can use preg_replace as an one-stop shop for this type of manipulation:
$array = preg_replace('/(.*);VALUE=DATE(.*)/', '$1$2T000000', $array);
The regular expression matches any string that contains ;VALUE=DATE and captures whatever precedes and follows it into capturing groups (referred to as $1 and $2 in the replacement pattern). It then replaces that string with $1 concatenated to $2 (effectively removing the search target) and appends "T000000" to the result.
The naive approach would be to loop over each element and check for ;VALUE=DATE. If it exists, remove it and append T000000.
foreach ($array as $key => $value) {
if (strpos($value, ';VALUE=DATE') !== false) {
$array[$key] = str_replace(";VALUE=DATE", "", $value) . "T000000";
}
}
You are correct str_replace() is the function that you are looking for. In addition you can use the concatenation operator . to append your string to the end of the new string. Is this what you are looking for?
$array[1] = str_replace(";VALUE=DATE", "", $array[1])."T000000";
$array[2] = str_replace(";VALUE=DATE", "", $array[2])."T000000";
for($i=0;$i<count($array);$i++){
if(strpos($array[$i], ";VALUE=DATE")){//look for the text into the string
//Text found, let's replace and append
$array[$i]=str_replace(";VALUE=DATE","",$array[$i]);
$array[$i].="T000000";
}
else{
//text not found in that position, will not replace
//Do something
}
}
If you want just to replace, just do it
$array=str_replace($array,";VALUE=DATE","");
And will replace all the text in all the array's positions...

Categories