I've been fighting with this for a while, i have this string :
storage/12426--the sunflower boys--07-09-2014/Authorization letter/Authorization letter--4--09-15-2015--15-39.pdf
and I would love to only get this part 07-09-2014 which lies between the first two slashes.
So far I came up with this: --[^/]* which only gives me --the sunflower boys--07-09-2014.
How do I get what im looking for?
Use digits \d match:
/^[^/]*\/[^/]*(\d\d-\d\d-\d\d\d\d)\//
You can use a capture group within 2 negated character class :
\/[^\/]*(\d{2}-\d{2}-\d{4})[^\/]*\/
See demo https://regex101.com/r/mL3aF7/1
If the formatting is consistent, you can split on / and take the second group, then split on -- and take the third.
$date = explode('--', explode('/', $str)[1])[2];
You can use match reset \K based regex:
--[^-]*--\K[^/]*
RegEx Demo
Related
I'm a regex-noobie, so sorry for this "simple" question:
I've got an URL like following:
http://stellenanzeige.monster.de/COST-ENGINEER-AUTOMOTIVE-m-w-Job-Mainz-Rheinland-Pfalz-Deutschland-146370543.aspx
what I'm going to archieve is getting the number-sequence (aka Job-ID) right before the ".aspx" with preg_replace.
I've already figured out that the regex for finding it could be
(?!.*-).*(?=\.)
Now preg_replace needs the opposite of that regular expression. How can I archieve that? Also worth mentioning:
The URL can have multiple numbers in it. I only need the sequence right before ".aspx". Also, there could be some php attributes behind the ".aspx" like "&mobile=true"
Thank you for your answers!
You can use:
$re = '/[^-.]+(?=\.aspx)/i';
preg_match($re, $input, $matches);
//=> 146370543
This will match text not a hyphen and not a dot and that is followed by .aspx using a lookahead (?=\.aspx).
RegEx Demo
You can just use preg_match (you don't need preg_replace, as you don't want to change the original string) and capture the number before the .aspx, which is always at the end, so the simplest way, I could think of is:
<?php
$string = "http://stellenanzeige.monster.de/COST-ENGINEER-AUTOMOTIVE-m-w-Job-Mainz-Rheinland-Pfalz-Deutschland-146370543.aspx";
$regex = '/([0-9]+)\.aspx$/';
preg_match($regex, $string, $results);
print $results[1];
?>
A short explanation:
$result contains an array of results; as the whole string, that is searched for is the complete regex, the first element contains this match, so it would be 146370543.aspx in this example. The second element contains the group captured by using the parentheeses around [0-9]+.
You can get the opposite by using this regex:
(\D*)\d+(.*)
Working demo
MATCH 1
1. [0-100] `http://stellenanzeige.monster.de/COST-ENGINEER-AUTOMOTIVE-m-w-Job-Mainz-Rheinland-Pfalz-Deutschland-`
2. [109-114] `.aspx`
Even if you just want the number for that url you can use this regex:
(\d+)
I am trying to set-up a quite complex regexp, but I can't avoid just one element from not-match list.
My regular expression is:
1234567-8_abc((?!_ABC|_DEFGHI)[\w]?)*(\.ios|\.and)
What I have to exclude is:
1234567-8_abc.ios
1234567-8_abc_DEFGHI.ios
1234567-8_abc_ABC.ios
Instead, what I have to include is:
1234567-8_abc_1UP.ios
1234567-8_abc_FI.ios
1234567-8_abc_gmg.ios
1234567-8_abc_1UP.and
1234567-8_abc_FI.and
1234567-8_abc_gmg.and
1234567-8_abc_ddd.and
1234567-8_abc_qwert.ios
1234567-8_abc_88.ios
Well, I can't exclude the first option (1234567-8_abc.ios).
I tried it here.
How can I achieve this?
Thank you!
You can use this pattern:
1234567-8_abc_[^_.]++(?<!_ABC|_DEFGHI)\.(?:ios|and)
Note: I assume that each substring between _ and .ios doesn't contain a dot or an underscore.
The possessive quantifier ++ is necessary to fail faster with the less possible backtracking steps
This regex matches your examples in PHP:
1234567-8_abc_((?!ABC|DEFGHI)[\w]?)*(\.ios|\.and)
Add a negative lookahead like below,
1234567-8_abc(?!_ABC|_DEFGHI)\w+(\.ios|\.and)
DEMO
(?!_ABC|_DEFGHI) Negative lookahead asserts that the string following _abc wouldn't be _ABC or _DEFGHI . And it must have one or more word characters before .ios or .and. So it won't match this 1234567-8_abc.ios string.
1234567-8_abc(?:(?!_ABC|_DEFGHI)\w)+(\.ios|\.and)
Try this.Your regex has left \w after 1234567-8_abc optional.Just made it compulsary.See demo.
http://regex101.com/r/bB8jY7/1
I'm matching patterns with reg_ex as in
$Structure = 'C:N:X:A:V:T:J:N:G:T:N:N:C:J:N:C:A:J:N:.:';
preg_match_all('/(T:|G:|L:|D:).*?(G:|i:|X:|\.:)/', $Structure, $arr, PREG_SET_ORDER);
the results I get are
T:J:N:G: , T:N:N:C:J:N:C:A:J:N:.:
How can I modify the query so that the deliminator (G:|i:|X:|.:) of the match is not included in the find, but will bu used in the next search. In other words make the result look as bellow:
T:J:N: , G:T:N:N:C:J:N:C:A:J:N:
instead?
Is this possible?
Thanks
Yes, instead of making your 2nd capturing group consume the input, turn it into a positive lookahead:
/(T:|G:|L:|D:).*?(?=(?:G:|i:|X:|\.:))/
Now, instead of matching (and consuming) the delimiter, this:
(?=(?:G:|i:|X:|\.:))
States that the regex must assert that the delimiter is present from the current point forward, i.e. a positive lookahead.
This results in:
"T:J:N:, G:T:N:N:C:J:N:C:A:J:N:"
It is possible by lookaheads, with the following syntax:
(?=G:|i:|X:|\.:)
That will not consume the piece that matches the regex.
On a side note, the delimiter means the slashes that you have enclosing your regex and not the capturing group you have.
Let say I have the following string:
getPasswordLastChangedDatetime
How would I be able to split that up by capital letters so that I would be able to get:
get
Password
Last
Changed
Datetime
If you only care about ASCII characters:
$parts = preg_split("/(?=[A-Z])/", $str);
DEMO
The (?= ..) construct is called lookahead [docs].
This works if the parts only contain a capital character at the beginning. It gets more complicated if you have things like getHTMLString. This could be matched by:
$parts = preg_split("/((?<=[a-z])(?=[A-Z])|(?=[A-Z][a-z]))/", $str);
DEMO
Asked this a little too soon, found this:
preg_replace('/(?!^)[[:upper:]]/',' \0',$test);
For instance:
(?:^|\p{Lu})\P{Lu}*
No need to over complicated solution. This does it
preg_replace('/([A-Z])/',"\n".'$1',$string);
This doens't take care of acronyms of course
Use this: [a-z]+|[A-Z][a-z]* or \p{Ll}+|\p{Lu}\p{Ll}*
preg_split("/(?<=[a-z])(?=[A-Z])/",$password));
preg_split('#(?=[A-Z])#', 'asAs')
i'm new to regular expressions and would like to match the first and last occurrences of a term in php. for instance in this line:
"charlie, mary,bob,bob,mary, charlie, charlie, mary,bob,bob,mary,charlie"
i would like to just access the first and last "charlie", but not the two in the middle. how would i just match on the first and last occurrence of a term?
thanks
If you know what substring you're looking for (ie. it's not a regex pattern), and you're just looking for the positions of your substrings, you could just simply use these:
strpos — Find position of first occurrence of a string
strrpos — Find position of last occurrence of a char in a string
Try this regular expression:
^(\w+),.*\1
The greedy * quantifier will take care that the string between the first word (\w+) and another occurrence of that word (\1, match of the first grouping) is as large as possible.
You need to add ^ and $ symbols to your regular expression.
^ - matches start of the string
$ - matches end of the string
In your case it will be ^charlie to match first sample and charlie$ to match last sample. Or if you want to match both then it will be ^charlie|charlie$.
See also Start of String and End of String Anchors for more details about these symbols.
Try exploding the string.
$names = "charlie, mary,bob,bob,mary, charlie, charlie, mary,bob,bob,mary,charlie";
$names_array = explode(",", $names);
After doing this, you've got an array with the names. You want the last, so it will be at position 0.
$first = $names_array[0];
It gets a little trickier with the last. You have to know how many names you have [count()] and then, since the array starts counting from 0, you'll have to substract one.
$last = $names_array[count($names_array)-1];
I know it may not be the best answer possible, nor the most effective, but I think it's how you really start getting programming, by solving smaller problems.
Good luck.