Replace specific character inbetween brackets - php

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

Related

PHP rtrim() or similar function for removing X amount of characters from string

This should be pretty basic. I've searched all over the best matching function (as far as I can see from PHP Manual is rtrim)
I've got a string. I want to remove X-amount of characters from, specifically the first 4 characters from the string.
EXAMPLE:
Fri, Dec 1, 2017
Sat, Dec 2, 2017
Sat, Dec 2, 2017
I would like to remove the first 4 characters from the left including white space after comma in order for me to have a date I can work with without day of week.
Now according to manual and W3Schools rtrim() enables you to do the above. However as I understand it, you have to put in the characters / text you want to be trimmed from string.
My problem is the days of the week will alternate from MON - SUN thus I can not put specific characters.
I'm trying to trim with index numbers starting from left 0-4
So at the end:
Fri, Dec 1, 2017
Should read
Dec 1, 2017
Try;
substr("Fri, Dec 1, 2017", 5);

What pattern to use in preg_match to get value from string

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.

PHP regex sytax with preg_replace

PHP REGEX is a weakness of mine, but still I manage to get some things done with online tools. Consider the following:
A subject string which generally follows this pattern: 1551 UTC 04 June 2012
I want to extract the "04" and assign it to the $day variable using below:
$day = preg_replace("/^([0-9]{4})\s([A-Z]{3})\s([0-9]{2})\s([A-Za-z]{3,})\s([0-9]{4})$/", "$3", $weather['date']);
This works on the following website: http://sqa.fyicenter.com/Online_Test_Tools/Test_Regular_Expression_Search_Replace.php
but I can't get it to work in my script... $day would equal the whole subject string.
The result of your var_dump() is string(38) "1551 UTC 04 June 2012 ". It has 38 chars while it should be only 21. So it looks like there are multiple whitespaces in the string.
Try to trim() your input string and replace \s with \s+ to support multiple whitespaces:
$day = preg_replace("/^([0-9]{4})\s+([A-Z]{3})\s+([0-9]{2})\s+([A-Za-z]{3,})\s+([0-9]{4})$/", "$3", trim($weather['date']));
you say preg_replace, but I think you want to use preg_match(). Is that correct that you don't want to replace the "04" but you just want to put it into a the variable $day? If so use preg_match(). In your description you say you want to capture only the "04" part, but your regex has many capture groups (anything within "()" is a capture group and will be returned in the array you give to preg_match).

PHP: preg replace date time

how can i replace date/time in this format 'Fri Mar 23 15:21:08 2012' with preg_replace?
Date in this format is present couple of times in my text and i need to replace it with current time/date.
Thanks,
Chris
Well, what you need is an expression that will match 3 letters (Fri) followed by a space and another three letters (Mar).
First we need to match some letters:
/[a-z]/
We can match exactly 3 letters like this:
/[a-z]{3}/
...and we'll need it to be case insensitive:
/[a-z]{3}/i
...so the first part is just:
/[a-z]{3} [a-z]{3}/i
Next, we need to match either 1 or 2 numerics. A numeric can be represented with the escape sequence \d, so we'd use:
/\d{1,2}/
Next we match the time string, using the same escape sequence:
/\d{2}:\d{2}:\d{2}/
...followed by a final 4 digit year:
/\d{4}/
Put it all together and we get:
/[a-z]{3} [a-z]{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}/i
// Fri Mar 23 15 : 21 : 08 2012
Now, we need to replace it with the current date and time. The usual place we'd go for that is the date() function, but how to we get that into the replacement dynamically? Well we could pass it as a string literal, or we could use a callback function to get it from preg_replace_callback(). But, preg_replace() gives us the e modifier which causes the replacement string to be evaluated for PHP code. We have to be careful and sparing with it's use, as with any PHP eval(), but this is a legitimate use case.
So our final PHP code looks like this:
preg_replace(
'/[a-z]{3} [a-z]{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}/ie',
"date('D M j H:i:s Y')",
$str
);
See it working
I think listing the finite sets of options is kind of better for these task and it will also save you from false positives. These are the patterns to match each part of the date format:
Days: (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)
Months: (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
Day: \d{1,2}
Time: \d{1,2}:\d{2}:\d{2}
Year: \d{4}
Putting everything together:
(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d{1,2}:\d{2}:\d{2} \d{4}
The code might look like:
$current_date = date('D M j H:i:s Y');
$text = preg_replace(
'/(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d{1,2}:\d{2}:\d{2} \d{4}/i',
$current_date,
$text
);
See a working example.
preg_replace('/Fri Mar 23 15:21:08 2012/',date('D M d H:i:s Y'),$string);
Normally do what you want.

Searching for data within a string. Regular expressions?

I have some strings I need to scrape data from. I need a simple way of telling PHP to look in the string and delete data before and after the part I need. An example is:
When: Sat 19 Sep 2009 22:00 to Sun 20 Sep 2009 03:00&nbsp;
I want to delete the "When: " and then remove the & and everything after it. Is this a Regex thing? Not really used them before.
I would not use regular expressions for this.
$data = substr($input, 6, strpos($input, '&') - 6);
Yes, regex can do this kind of thing in its sleep.
$result = preg_replace('/When:(.*)&.*/', '$1', $text);
UPDATE
If you want to find the date range only, in the middle of a lot of other text, here is a crude regex that will match the one in the question...
if (preg_match('/[a-z]{3} [0-9]{2} [a-z]{3} [0-9]{4} [0-9]{2}:[0-9]{2} to [a-z]{3} [0-9]{2} [a-z]{3} [0-9]{4} [0-9]{2}:[0-9]{2}/i', $text, $regs)) {
$result = $regs[0];
} else {
$result = "";
}
So you would want to keep "Sat 19 Sep 2009 22:00 to Sun 20 Sep 2009 03:00"
Well you can go for a regexp alright. I don't know much about the Regexp in PHP, but in PERL, you could do somehing like
/^When: (.*)\ $/ .
The (.*) could then be used to get all that is what you want to keep. In PERL, that would be looking the $1 var.
Or you could do something like
/^When: (.)\&.$/ if the content after the & is variable.
Also, you must watch out. If the string you want to keep contains &, then it might a little more tricky.
But RegExp are usually the way to got for this type of work.

Categories