Preg_match for a date - php

I am trying to match a date in PHP using preg_match, split it and assign parts of it to an array, the date looks like "20100930", here is the code I am using:
// Make the tor_from date look nicer
$nice_from = $_POST['tor_from'];
$matches = array();
$ideal_from = '';
preg_match('/\d{4}\\d{2}\\d{2}\/', $nice_from, $matches, PREG_OFFSET_CAPTURE, 0);
// if (isset($matches[0])) $nice_from = $matches[0];
echo $matches[0];
echo "<br />";
echo $matches[1];
echo "<br />";
echo $matches[2];
echo "<br />";
echo $matches[3];
echo "<br />";
Ive been using:
http://php.net/manual/en/function.preg-match.php and PHP preg_match question to formulate ideas on how to do this, however I have had no luck in getting it to work. Any help would be greatly appreciated.

Although regex isn't really a good solution for parsing a date in YYYYMMDD format, let's walk through why your pattern isn't working.
Your pattern \d{4}\\d{2}\\d{2}\ says: "match 4 digits (\d{4}), followed by a backslash character (\\), followed by the letter d twice (d{2}), followed by another backslash (\\) and then finally another two d's (d{2})."
As you might have figure out by now, you don't want the double slashes!
\d{4}\d{2}\d{2}
Will match 4 digits, followed by 2 digits, and then another 2 digits.
Furthermore, you are not specifying any capturing groups, so your subpatterns will never be filled. What you probably meant was:
(\d{4})(\d{2})(\d{2})
See this in action at http://www.ideone.com/iAy7K. Note that there really isn't any reason in your case to be specifying the PREG_OFFSET_CAPTURE flag (which returns the position of each match) or 0 for the offset.

Forget preg_match, use strtotime():
echo date('Y/m/d', strtotime($_POST['tor_from']));

It's better like this, using preg_match and indexed names.
$res = preg_match("/(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})/", $date, $matches);
And Matches will look like:,
array('year' => 2010, 'month' => 12, 'day' => 07);
Cheers.

Regex is not the best way to go here if the pattern is this simple. Use substr instead:
$date = '20100930';
$year = substr($date,0,4);
$month = substr($date,4,2);
$day = substr($date,6,2);

You need to put some parenthesis around the patterns that you would like to show up in $matches. Also i don't think you want the double \\ in between your \d's because that will escape the second \ and leave you matching a literal 'd'.

Related

Cut (crop) some text in a string

I have a string with 3 block parameters (words, digits, slashes) and i need to separate it and print only last block parameters. I do this:
<?php
$howmuch="17шт / 119ml / 255грн";
echo preg_replace("/(\\d\\w\\ / )(\\d\\w\\ / )(\\d\\w\\ / )$/i", "$3", $howmuch);
?>
I need to print only 255грн, but my script do nothing. Please help me to fix a problem. Thank you to all.
If the format is fixed, you may get the value without any regex using
explode(" / ", $howmuch)[2]
See the PHP demo. It will split the string with space-/-space and get you the third element of the resulting array.
Alternatively, you may extract a number with грн after it using a preg_match operation (this approach lets you find the match regardless of how many / there are before or after the match):
$howmuch="17шт / 119ml / 255грн";
if (preg_match("/\d+\s*грн/ui", $howmuch, $results)) {
echo $results[0];
}
See the PHP demo.
If the value can contain a fractional part, you may use "/\d+(?:[.,]\d+)?\s*грн/ui" where (?:[.,]\d+)? matches an optional sequence of a . or , followed with 1+ digits.
Why not keep it simple and understandable, for instance, like this:
$howMuch = '17шт / 119ml / 255грн';
$blocks = explode('/',$howMuch);
echo $blocks[2];
This doesn't need much explaining, or working out why it does what it does.
All regex free options:
echo explode('/', $howMuch)[2];
if you need to ensure string has three sections
if (substr_count($howmuch, '/') > 1) {
echo explode('/', $howMuch)[2];
}
if you are on a php version prior to 5.4
$chunks = explode('/', $howMuch);
echo $chunks[2];

How to make regex with this format "image(numeric, string)"?

i want to make regex to detect this format image(numeric, string). ex: image(100, 'test').
i have tried this one, but just detect the image(numeric)
/image\((\d+)\)/
Any help with second parameter and the ,?
Also how i can get the second parameter?
You can try the following pattern:
/image\(\d+,\s*'.+?'\)/
I removed the capture group since it would be not needed if using the regex for validation only.
Demo
If you want to capture the number and text, then use capture groups:
$input = "code image(123, 'meh') more code";
if (preg_match("/image\((\d+),\s*'(.+?)'\)/", $input, $m)) {
echo "match";
}
$number = $m[1];
$text = $m[2];
Try this:
image\((\d+), '(.+?)'\)
The . matches anything and the rest is pretty much self-explanatory. Group 1 is your number, group 2 is the string.
You can try this one:
image\(\s*\d+\s*\,\s*'.*'\s*\)

Searching and extracting from a String using regex in PHP [duplicate]

This question already has answers here:
How do I check if a string contains a specific word?
(36 answers)
Closed 7 years ago.
I have the following string in PHP:
$cars = "Ford Chevrolet Dodge Chrysler";
I am required to output which words have various properties such as: Which word ends in 'let'? Or which word starts with 'Fo'?
I am unsure how to approach this. I am familiar enough with regex formatting, and I have gotten my preg_match to identify matches, but that's only results given in 1 or 0.
So should I split up the words using the space as a delimiter and search each one for matches individually? Or is there a simpler way of going about this?
I am aware of the preg_split function, but I don't know how to actually access the split strings.
$cars = "Ford Chevrolet Dodge Chrysler";
$param1 = '/(let)+/';
$param2 = '/(fo)+/';
echo preg_match($param1, $cars);
echo preg_match($param2, $cars);
I am aware that this doesn't work, but it prints 1s and verifys to me that matches are being found for both parameters. I just don't know how to extract the full 'Chevrolet' and full 'Ford' for parameter 1 and 2 respectively.
I am sure you're going to be able to figure out how to insert user input into variables $start or $end – just in case: ask them if they want the input string at the beginning or at the end, and based on the answer, save the string to search in to either $start or $end.
$string = "Ford Chevrolet Dodge Chrysler";
$start = "";
$end = "let";
if(!empty($start))
preg_match_all("#" . $start . "\w+#", $string, $matches);
elseif(!empty($end))
preg_match_all("#\w+" . $end ."#", $string, $matches);
else
die("Nothing has been set!");
print_r($matches);
This is the case implemented for all the words ending with a let in your example string. Bear in mind the regex is only going to match word characters. If you're going to get more complicated strings, maybe another solution should be created.
To simply echo all the matches, use foreach loop like this instead of the print_r function:
if(!empty($matches))
{
foreach($matches as $match)
echo $match . "<br>";
}
else
die("Nothing matched!");

php - Get string before nth dash (-)

I have a string that looks something like this:
abc-def-ghi-jkl-mno-pqr-stu-vwx-yz I'd like to get the content BEFORE the 4th dash, so effectively, I'd like to get abc-def-ghi-jkl assigned to a new string, then I'd like to get mno assigned to a different string.
How could I go about doing this? I tried using explode but that changed it to an array and I didn't want to do it that way.
Try this:
$n = 4; //nth dash
$str = 'abc-def-ghi-jkl-mno-pqr-stu-vwx-yz';
$pieces = explode('-', $str);
$part1 = implode('-', array_slice($pieces, 0, $n));
$part2 = $pieces[$n];
echo $part1; //abc-def-ghi-jkl
echo $part2; //mno
See demo
http://php.net/manual/en/function.array-slice.php
http://php.net/manual/en/function.explode.php
http://php.net/manual/en/function.implode.php
Can you add your source code? I done this one before but I cant remember the exact source code I used. But I am pretty sure I used explode and you can't avoid using array.
EDIT: Mark M answer is right.
you could try using substr as another possible solution
http://php.net/manual/en/function.substr.php
If I see where you are trying to get with this you could also go onto substr_replace
I guess an alternative to explode would be to find the position of the 4th - in the string and then get a substring from the start of the string up to that character.
You can find the position using a loop with the method explained at find the second occurrence of a char in a string php and then use substr(string,0,pos) to get the substring.
$string = "abc-def-ghi-jkl-mno-pqr-stu-vwx-yz";
$pos = -1;
for($i=0;$i<4;$i++)
$pos = strpos($string, '-', $pos+1);
echo substr($string, 0, $pos);
Code isn't tested but the process is easy to understand. You start at the first character (0), find a - and on the next loop you start at that position +1. The loop repeats it for a set number of times and then you get the substring from the start to that last - you found.

How to write regex to return only certain parts of this string?

So I'm working on a project that will allow users to enter poker hand histories from sites like PokerStars and then display the hand to them.
It seems that regex would be a great tool for this, however I rank my regex knowledge at "slim to none".
So I'm using PHP and looping through this block of text line by line and on lines like this:
Seat 1: fabulous29 (835 in chips)
Seat 2: Nioreh_21 (6465 in chips)
Seat 3: Big Loads (3465 in chips)
Seat 4: Sauchie (2060 in chips)
I want to extract seat number, name, & chip count so the format is
Seat [number]: [letters&numbers&characters] ([number] in chips)
I have NO IDEA where to start or what commands I should even be using to optimize this.
Any advice is greatly appreciated - even if it is just a link to a tutorial on PHP regex or the name of the command(s) I should be using.
I'm not entirely sure what exactly to use for that without trying it, but a great tool I use all the time to validate my RegEx is RegExr which gives a great flash interface for trying out your regex, including real time matching and a library of predefined snippets to use. Definitely a great time saver :)
Something like this might do the trick:
/Seat (\d+): ([^\(]+) \((\d+)in chips\)/
And some basic explanation on how Regex works:
\d = digit.
\<character> = escapes character, if not part of any character class or subexpression. for example:
\t
would render a tab, while \\t would render "\t" (since the backslash is escaped).
+ = one or more of the preceding element.
* = zero or more of the preceding element.
[ ] = bracket expression. Matches any of the characters within the bracket. Also works with ranges (ex. A-Z).
[^ ] = Matches any character that is NOT within the bracket.
( ) = Marked subexpression. The data matched within this can be recalled later.
Anyway, I chose to use
([^\(]+)
since the example provides a name containing spaces (Seat 3 in the example). what this does is that it matches any character up to the point that it encounters an opening paranthesis.
This will leave you with a blank space at the end of the subexpression (using the data provided in the example). However, his can easily be stripped away using the trim() command in PHP.
If you do not want to match spaces, only alphanumerical characters, you could so something like this:
([A-Za-z0-9-_]+)
Which would match any letter (within A-Z, both upper- & lower-case), number as well as hyphens and underscores.
Or the same variant, with spaces:
([A-Za-z0-9-_\s]+)
Where "\s" is evaluated into a space.
Hope this helps :)
Look at the PCRE section in the PHP Manual. Also, http://www.regular-expressions.info/ is a great site for learning regex. Disclaimer: Regex is very addictive once you learn it.
I always use the preg_ set of function for REGEX in PHP because the PERL-compatible expressions have much more capability. That extra capability doesn't necessarily come into play here, but they are also supposed to be faster, so why not use them anyway, right?
For an expression, try this:
/Seat (\d+): ([^ ]+) \((\d+)/
You can use preg_match() on each line, storing the results in an array. You can then get at those results and manipulate them as you like.
EDIT:
Btw, you could also run preg_match_all on the entire block of text (instead of looping through line-by-line) and get the results that way, too.
Check out preg_match.
Probably looking for something like...
<?php
$str = 'Seat 1: fabulous29 (835 in chips)';
preg_match('/Seat (?<seatNo>\d+): (?<name>\w+) \((?<chipCnt>\d+) in chips\)/', $str, $matches);
print_r($matches);
?>
*It's been a while since I did php, so this could be a little or a lot off.*
May be it is very late answer, But I am interested in answering
Seat\s(\d):\s([\w\s]+)\s\((\d+).*\)
http://regex101.com/r/cU7yD7/1
Here's what I'm currently using:
preg_match("/(Seat \d+: [A-Za-z0-9 _-]+) \((\d+) in chips\)/",$line)
To process the whole input string at once, use preg_match_all()
preg_match_all('/Seat (\d+): \w+ \((\d+) in chips\)/', $preg_match_all, $matches);
For your input string, var_dump of $matches will look like this:
array
0 =>
array
0 => string 'Seat 1: fabulous29 (835 in chips)' (length=33)
1 => string 'Seat 2: Nioreh_21 (6465 in chips)' (length=33)
2 => string 'Seat 4: Sauchie (2060 in chips)' (length=31)
1 =>
array
0 => string '1' (length=1)
1 => string '2' (length=1)
2 => string '4' (length=1)
2 =>
array
0 => string '835' (length=3)
1 => string '6465' (length=4)
2 => string '2060' (length=4)
On learning regex: Get Mastering Regular Expressions, 3rd Edition. Nothing else comes close to the this book if you really want to learn regex. Despite being the definitive guide to regex, the book is very beginner friendly.
Try this code. It works for me
Let say that you have below lines of strings
$string1 = "Seat 1: fabulous29 (835 in chips)";
$string2 = "Seat 2: Nioreh_21 (6465 in chips)";
$string3 = "Seat 3: Big Loads (3465 in chips)";
$string4 = "Seat 4: Sauchie (2060 in chips)";
Add to array
$lines = array($string1,$string2,$string3,$string4);
foreach($lines as $line )
{
$seatArray = explode(":", $line);
$seat = explode(" ",$seatArray[0]);
$seatNumber = $seat[1];
$usernameArray = explode("(",$seatArray[1]);
$username = trim($usernameArray[0]);
$chipArray = explode(" ",$usernameArray[1]);
$chipNumber = $chipArray[0];
echo "<br>"."Seat [".$seatNumber."]: [". $username."] ([".$chipNumber."] in chips)";
}
you'll have to split the file by linebreaks,
then loop thru each line and apply the following logic
$seat = 0;
$name = 1;
$chips = 2;
foreach( $string in $file ) {
if (preg_match("Seat ([1-0]): ([A-Za-z_0-9]*) \(([1-0]*) in chips\)", $string, $matches)) {
echo "Seat: " . $matches[$seat] . "<br>";
echo "Name: " . $matches[$name] . "<br>";
echo "Chips: " . $matches[$chips] . "<br>";
}
}
I haven't ran this code, so you may have to fix some errors...
Seat [number]: [letters&numbers&characters] ([number] in chips)
Your Regex should look something like this
Seat (\d+): ([a-zA-Z0-9]+) \((\d+) in chips\)
The brackets will let you capture the seat number, name and number of chips in groups.

Categories