Regex Optional Matches - php

I'm trying to match two types of strings using the preg_match function in PHP which could be the following.
'_mything_to_newthing'
'_onething'
'_mything_to_newthing_and_some_stuff'
In the third one above, I only want the "mything" and "newthing" so everything that comes after the third part is just some optional text the user could add. Ideally out of the regex would come in the cases of above;
'mything', 'newthing'
'onething'
'mything', 'newthing'
The patterns should match a-zA-Z0-9 if possible :-)
My regex is terrible, so any help would be appreciated!
Thanks in advanced.

Assuming you're talking about _ deliminated text:
$regex = '/^_([a-zA-Z0-9]+)(|_to_([a-zA-Z0-9]+).*)$/';
$string = '_mything_to_newthing_and_some_stuff';
preg_match($regex, $string, $match);
$match = array(
0 => '_mything_to_newthing_and_some_stuff',
1 => 'mything',
2 => '_to_newthing_and_some_stuff',
3 => 'newthing',
);
As far as anything farther, please provide more details and better sample text/output
Edit: You could always just use explode:
$parts = explode('_', $string);
$parts = array(
0 => '',
1 => 'mything',
2 => 'to',
3 => 'newthing',
4 => 'and',
5 => 'some',
6 => 'stuff',
);
As long as the format is consistent, it should work well...

Related

How to set checkboxes in google sheets via API when appending data using PHP?

I already found something, that comes close to my question.
I am using the append-method because that´s exactly what I need and it works very well. I am not sure if I´m missing something here or the "append" does not support any kind of DataValidation.
Google shows in the example:
$response = $service->spreadsheets_values->append($spreadsheetId, $range, $requestBody);
the $requestBody is just a simple array:
$values = [
[
0 => $str,
1 => $str,
2 => $str,
3 => $str,
4 => $str,
5 => $str,
6 => $str,
7 => $str,
8 => $str
],
// Additional rows ...
];
$body = new Google_Service_Sheets_ValueRange(['values' => $values]);
I don´t see any way to integrate this code:
$dv = new Google_Service_Sheets_DataValidationRule();
$b = new Google_Service_Sheets_BooleanCondition();
$b->setType('BOOLEAN');
$dv->setCondition($b);
I tested to add this as a value like:
$values = [
[
0 => $str,
1 => $str,
2 => $str,
3 => $str,
4 => $str,
5 => $str,
6 => $str,
7 => $str,
8 => $dv, /* <====== TRY TO ADD A CHECKBOX */
],
// Additional rows ...
];
but this only leads to errors telling me, the values have a wrong structure.
At this point, I have no idea if "appending" supports any kind of "data validation" or not.
Thanks for any help.
In order to put the checkbox using Sheets API, the method of batchUpdate is required to be used.
Unfortunately, in the current stage, the checkbox cannot be put by the method of values.append.
This is the current answer for your question.
References:
Method: spreadsheets.batchUpdate
ExtendedValue
Method: spreadsheets.values.append

Parsing parameters from command line with RegEx and PHP

I have this as an input to my command line interface as parameters to the executable:
-Parameter1=1234 -Parameter2=38518 -param3 "Test \"escaped\"" -param4 10 -param5 0 -param6 "TT" -param7 "Seven" -param8 "secret" "-SuperParam9=4857?--SuperParam10=123"
What I want to is to get all of the parameters in a key-value / associative array with PHP like this:
$result = [
'Parameter1' => '1234',
'Parameter2' => '1234',
'param3' => 'Test \"escaped\"',
'param4' => '10',
'param5' => '0',
'param6' => 'TT',
'param7' => 'Seven',
'param8' => 'secret',
'SuperParam9' => '4857',
'SuperParam10' => '123',
];
The problem here lies at the following:
parameter's prefix can be - or --
parameter's glue (value assignment operator) can be either an = sign or a whitespace ' '
some parameters may be inside a quote block and can also have different, both separators and glues and prefixes, ie. a ? mark for the separator.
So far, since I'm really bad with RegEx, and still learning it, is this:
/(-[a-zA-Z]+)/gui
With which I can get all the parameters starting with an -...
I can go to manually explode the entire thing and parse it manually, but there are way too many contingencies to think about.
You can try this that uses the branch reset feature (?|...|...) to deal with the different possible formats of the values:
$str = '-Parameter1=1234 -Parameter2=38518 -param3 "Test \"escaped\"" -param4 10 -param5 0 -param6 "TT" -param7 "Seven" -param8 "secret" "-SuperParam9=4857?--SuperParam10=123"';
$pattern = '~ --?(?<key> [^= ]+ ) [ =]
(?|
" (?<value> [^\\\\"]*+ (?s:\\\\.[^\\\\"]*)*+ ) "
|
([^ ?"]*)
)~x';
preg_match_all ($pattern, $str, $matches);
$result = array_combine($matches['key'], $matches['value']);
print_r($result);
demo
In a branch reset group, the capture groups have the same number or the same name in each branch of the alternation.
This means that (?<value> [^\\\\"]*+ (?s:\\\\.[^\\\\"]*)*+ ) is (obviously) the value named capture, but that ([^ ?"]*) is also the value named capture.
You could use
--?
(?P<key>\w+)
(?|
=(?P<value>[^-\s?"]+)
|
\h+"(?P<value>.*?)(?<!\\)"
|
\h+(?P<value>\H+)
)
See a demo on regex101.com.
Which in PHP would be:
<?php
$data = <<<DATA
-Parameter1=1234 -Parameter2=38518 -param3 "Test \"escaped\"" -param4 10 -param5 0 -param6 "TT" -param7 "Seven" -param8 "secret" "-SuperParam9=4857?--SuperParam10=123"
DATA;
$regex = '~
--?
(?P<key>\w+)
(?|
=(?P<value>[^-\s?"]+)
|
\h+"(?P<value>.*?)(?<!\\\\)"
|
\h+(?P<value>\H+)
)~x';
if (preg_match_all($regex, $data, $matches)) {
$result = array_combine($matches['key'], $matches['value']);
print_r($result);
}
?>
This yields
Array
(
[Parameter1] => 1234
[Parameter2] => 38518
[param3] => Test \"escaped\"
[param4] => 10
[param5] => 0
[param6] => TT
[param7] => Seven
[param8] => secret
[SuperParam9] => 4857
[SuperParam10] => 123
)

PHP - searching a body of text with an array of needles, returning the keys of all matches

Looking to search a body of text and return the keys of any of the array elements that have been found within the text. I currently have the below which works but only returns True on the first element found.
$needles = [1 => 'shed', 5 => 'charge', 8 => 'book', 9 => 'car'];
$text = "Does anyone know how much Bentleys charge to put up a small shed please? Thanks";
if(preg_match('/'.implode('|', array_map('preg_quote', $needles)).'/i', $text)) {
echo "Match Found!";
}
However the output I need is;
[1 => 'shed', 5 => 'charge']
Can anybody help? I am going to be searching a lot of values so this needs to be a fast solution hence using preg_match.
The solution using array_filter and preg_match functions:
$needles = [1 => 'shed', 5 => 'charge', 8 => 'book', 9 => 'car'];
$text = "Does anyone know how much Bentleys charge to put up a small shed please? Thanks";
// filtering `needles` which are matched against the input text
$matched_words = array_filter($needles, function($w) use($text){
return preg_match("/" . $w . "/", $text);
});
print_r($matched_words);
The output:
Array
(
[1] => shed
[5] => charge
)

Extracting url from string php

I am trying to extract URL out of a string. The format of the string will be:
some text! some numbers http://linktoimage.com/image
I found this post earlier Extract URLs from text in PHP
and I think this solution mentioned there could work:
<?php
$string = "this is my friend's website http://example.com I think it is coll";
echo explode(' ',strstr($string,'http://'))[0]; //"prints" http://example.com
However I do not understand what it actually does. Would someone mind explaining this to me to me ?
You have this string:
this is my friend's website http://example.com I think it is coll
strstr($string,'http://') will return
http://example.com I think it is coll
explode(' ', ...) then will split this resulting string at the space character resulting in
array(
0 => 'http://example.com',
1 => 'I',
2 => 'think',
3 => 'it',
4 => 'is',
5 => 'coll'
)
and finally [0] returns the first item of this array, which is:
http://example.com
Further reading:
http://php.net/manual/en/function.strstr.php
http://php.net/manual/en/function.explode.php

PregMatch on 3 digits with a dot

I have numbers like theses:
1.80
2.75
#1.55
Theses numbers are in strings and I'm trying to get them throught preg_match. At this time I have this:
$pattern = '/ [0-9]{1}\.[0-9]{2}/';
$result = preg_match($pattern, $feed, $matches);
This works pretty well but I need more precision on my preg_match and I didn't found a solution.
With this pattern, numbers like 1.556 will be found. I don't want this, my numbers length will be 4 chars. dot included.
Also, here I am not able to catch the numbers starting by a #, only a space. How can I do this?
$result = preg_match($pattern, 'test 1.556 red #1.62 blue 2.33 ?', $matches);
Here the results needed are 1.62 and 2.33
As an alternative to regular expressions, PHP-Sanitization-Filters:
$array = explode(' ', 'test 1.556 red #1.62 blue 2.33 ?');
$result = filter_var_array(
array(
'convert' => $array
),
array(
'convert' => array(
'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
'flags' => FILTER_FLAG_ALLOW_FRACTION | FILTER_FORCE_ARRAY
)
)
);
var_dump(array_filter(array_map('floatval', $result['convert'])));
results in:
array(3) {
[1]=>
float(1.556)
[3]=>
float(1.62)
[5]=>
float(2.33)
}
The following pattern will match all numbers in the format of #.## with an optional leading space or at sign.
[ #]?(\d{1}\.\d{2})\b
Demo: http://regex101.com/r/eB4bL5
if you want it up to 4 precision and the # to be catched That is what you need
$pattern = '/ #*([0-9]{1}\.[0-9]{2})\b /';

Categories