What pattern to use in preg_match to get value from string - php

I have two strings
First One:
Date: Sat, 13 Jun 2015 13:26:05 +0100
Subject: Changing the balance: +50,00 CZK
Dear client,
Second One:
Date: Sat, 14 Jun 2015 14:58:05 +0100
Subject: Changing the balance: +75,00 CZK
Dear client,
And I really don't know what pattern to use if I want to get the number of CZKs from these strings. I need integer 50 from first string and integer 75 from second string (just integer not decimal with ,00).

This can really be as simple or as complex as you need it to be. In it's simplest form, you could look for a pattern that reads:
number.comma.number.space.CZK
this can be written as:
[0-9]+,[0-9]+\sCZK
[0-9] is a range, between 0-9 (number). The plus character means that at least 1 number is required. If you wanted to make this EXACTLY 2 numbers you could change [0-9]+ for [0-9]{2}
, is a comma...
[0-9]+ is another number (at least 1)
\s is a space
CZK is the string you're wanting to end with
You can expand upon this as you wish. Here is a working example: http://regexr.com/3baog
Edit:
If you wish to capture the 50 / 75, you need to wrap parenthesis around the part you're after, eg:
([0-9]+),[0-9]+\sCZK

Use positive lookahead to select the integer part of number before CZK
\d+(?=,\d*\s*CZK)
Explanation for the above regex can be seen from this DEMO
If you want to select the sign + or -, then you can add [+-]? at the beginning.

Related

check telephone number goes wrong

i use this to check if there is a 06 number in the string. the 06 number is always 10 numbers.
$string = "This is Henk 0612345678";
$number = preg_replace('/[^0-9.]+/', '', $string);
echo $number;
This is working good, but when the string is
$string = "This is 12Henk 0612345678";
The number is 120612345678
I dont want the 12 into it, but 12 is not always the same in the string.
How can i check only for a 10 digits number ?
Thanks
This could help you
/([ \w]+)(06[0-9.+]{8})/
the 1st () is the entire String before the 06 and the 2nd() is the Number starting with 06 and 8 digits.
The solution does not cover the case where a 06 comes before the number sequence
Rather than replacing everything that's not what you want, try searching for what you do want with preg_match.
That makes it a lot easier to be specific:
The number always starts 06, so you can hard-code that in your regex
That's followed by exactly 8 more digits, which you can specify as [0-9]{8} or \d{8} ("d" for "digit")
To avoid matching longer numbers, you can surround that with \b for "word break"
Put it together, and you get:
preg_match('/\b06\d{8}\b/', $string, $matched_parts);
This doesn't change $string, but gives you an array in $matched_parts containing the matched parts; see the preg_match documentation for a detailed explanation.

Replace specific character inbetween brackets

I want to replace , with :character that is located in between [].
So [Hello, as] a, booby will change to [Hello: as] a, booby. I cannot figure out how to match the comma within brackets, I can match the word inside brackets with
\[(.*)\] but I don't know how to pick the comma from there.
Also if I get [[Hello, as] a, booby], then I also want to change only the first comma. I tried to use * or + but it doesn't work.
I need this
[["Sender", "mail#text.org"], ["Date", "Fri, 09 Jun 2017 13:29:22 +0000"]]
To became this
[["Sender": "mail#text.org"], ["Date": "Fri, 09 Jun 2017 13:29:22 +0000"]]
I wanted to use preg_replace but I It was not the right solution.
preg_replace("/(\[[^],]*),/U" , ':', $arr)
returns
": mail#text.org"], : "Fri, 09 Jun 2017 13:29:22 +0000"]
This seems as simple as I can make it: (Demo Link)
(?<="),
It makes some assumptions about your nested psuedo array values.
PHP Implementation:
$in='[["Sender", "mail#text.org"], ["Date", "Fri, 09 Jun 2017 13:29:22 +0000"], ["Name", "Dude"]]';
echo preg_replace('/(?<="),/',':',$in);
Output:
[["Sender": "mail#text.org"], ["Date": "Fri, 09 Jun 2017 13:29:22 +0000"], ["Name": "Dude"]]
If this doesn't suit your actual strings, please provide a string where my pattern fails, so that I can adjust it. Extending the pattern to ensure that that comma follows the quoted "key" can be done like this: "[^"]+"\K, ...at a slightly higher step cost (but still not bad).
Try grouping everything before and after the comma, then put them back around the colon.
preg_replace('/(\[.*?),(.*?\])/','$1:$2',$string)
You can use a \G based pattern:
$str = preg_replace('~(?:\G(?!\A)|\[(?=[^][]*]))[^][,]*\K,~', ':', $str);
This kind of pattern starts with 2 subpatterns in an alternation:
\[(?=[^][]*]) that searches a [ followed by a ] without other brackets between them.
\G(?!\A) that matches at the position after a previous match
Then, in the two cases [^][,]*\K, reaches the next , that can only be between [ and ].
But since you also need to skip commas between double quotes, you have to match double quotes parts before an eventual comma. To do that, change [^][,]* to [^][",]*(?:"[^"\\]*(?s:\\.[^"\\]*)*"[^][",]*)*+
$str = preg_replace('~(?:\G(?!\A)|\[(?=[^][]*]))[^][",]*+(?:"[^"\\\\]*(?s:\\\\.[^"\\\\]*)*"[^][",]*)*+\K,~', ':', $str);
demo

create regex to match format of 00:00:00 for duration (not time)

Hi i'm using laravel and I want to validate create a regex which will allow a specific format for duration (not time as this can exceed a 24 hr format). so for example 124hrs 30 mins and 24 secs would be represented as follows 124:30:24. But the first value can be over 1 character and a number, the second value needs be a colon, the third value needs to be 2 characters and a number, the fourth value needs to be a colon and the fifth value needs to be 2 characters and a numbers.
Any ideas how I can create an regex that will achieve this to insert into the following array?
$rules = array(
'duration' => 'required|regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/'
);
invalid examples:
alphacharacters e.g. qwerty
0:0:0
0:
0
1
30:211:211
30:2111:2111
a:d:d
asd
valid examples:
01:00:00
1:00:00
30:21:21
330:21:21
1330:21:21
11330:21:21
basically any amount of hours.
Give your examples this regex should suffice:
^\d+:\d{2}:\d{2}$
Demo: https://regex101.com/r/kO4xN2/2
\d is a number
+ is a quantifier meaning one or more of the preceding character (or group)
{} is an amount of characters to allow (you can give it a range as well)
^$ are anchors, so the string must be an exact match, if there is more content in the string this should be removed.

Finding the last occurrence of href

I am trying to find a link using regexp which appears just before textABCXYZ123 string in below HTML .
lorem ispum...<strong>FIRSTlink </strong><br>
1 points| Saved Jan 08, 2014 at 00:49 <span class=notes_box>ANOTHERLINK</span>.
... more text........... more text........
... more text.......<strong>other link </strong><br>
1 points| Saved Jan 08, 2014 at 00:49 <span class=notes_box>ANOTHERLINK</span>.
... more text........... more text........
<strong>somewhere to go </strong><br>
1 points| Saved Jan 08, 2014 at 00:49 <span class=notes_box>textABCXYZ123</span>
...
... more text..........<strong>other link </strong><br>
1 points| Saved Jan 08, 2014 at 00:49 <span class=notes_box>ANOTHERLINK</span>.
... more text........... more text........
There are many links and I need to capture the link which appears just before textABCXYZ123 string. i tried below regex but it is returning me first link instead of last one:
$find_string = 'ABCXYZ123';
preg_match('#href="(.*)".*text'.$find_string.'#sU',$html,$match);
// so final resutl is "http://www.site.com/link/123" which is first link
Can someone guide me how can I capture that link just before my string textABCXYZ123? P.S I know about xpath and simple html dom but I would like to match with regexp. Thanks for any input.
You could maybe try the regex:
href="([^"]*)">(?=(?:(?!href).)*textABCXYZ123)
Like so?
$find_string = 'ABCXYZ123';
preg_match('~href="([^"]*)">(?=(?:(?!href).)*text'.$find_string.')~sU',$html,$match);
regex101 demo
The first part is href="([^"]*)"> and shouldn't be too hard to understand. It matches href=" and then any number of non-quote characters, followed by quotes and >.
(?=(?:(?!href).)*textABCXYZ123) first is a positive lookahead. (A positive lookahead has the format (?= ... )) It will make sure that there is what's inside to say that there is a match.
For instance, a(?=.*b) matches any a, as long as there is any characters, then a b somewhere after the a (also means it matches a as long as there's a b somewhere after it).
So, href="([^"]*)"> will match only if there is (?:(?!href).)*textABCXYZ123 somewhere ahead.
(?:(?!href).)* is a modified .*, because the negative lookahead (format (?! ... )) makes sure no href is matched. You could say it's the opposite of a positive lookahead:
a(?!.*b) matches any a as long as it is not followed by a b.
(?s)href=[^<]+</a>(?!.*(href).*(textABCXYZ123))(?=.*(textABCXYZ123))
Could also try this, let me know if you want an explantation

problem with preg_match

I have to validate for a Laser Credit card. The card starts with either 6304, 6706, 6709, 6771 and is 16 or 19 digits in length. I have a preg_match and I am passing in the card number starting with 6706 and has 19 digits but it returns false.
// Laser (Laser) P: 6304, 6706, 6709, 6771 L: 16,19
} elseif (preg_match('/^(?:[6304|6706|6709|6771])\d{12,15}$/', $number)) {
$type = 'laser';
/^6(?:304|706|709|771)(?:\d{12}|\d{15})$/
Broken down:
/^ # start of line
6(?:304|706|709|771) # your 6xxx codes
(?:\d{12}|\d{15}) # 12 (16-4) or 15 (19-4) more numbers
$/ # end of pattern
To point out the mistakes you had:
(?:[6304|6706|6709|6771])
Remember that [] is a CLASS. That means to look for any of those characters within the brackets. If you're going for either/or, you need to use a group ().
Fixed it should look like: (?:6304|6706|6709|6771)
\d{12,15}
My understanding is you need fixed-length of numbers, not a variable one. Your quantifier is saying it can be 12, 13, ..., 15 more numbers. We only want 12 OR 15 more.

Categories