I have variable strings like the below:
The.Test.String.A01Y18.123h.WIB-DI.DO5.1.K.314-ECO
The.Regex.F05P78.123h.WIB-DI.DO5.1.K.314-EYT
Word.C05F78.342T.DSW-RF.EF5.2.F.342-DDF
I would like to extract this part of these string in PHP dynamically and i was looking at using regex but haven't had much success:
The.Test.String.A01Y18
The.Regex.F05P78
Word.C05F78
And ultimately to:
The Test String A01Y18
The Regex F05P78
Word C05F78
The first part of the text will be variable in length and will separate each word with a period. The next part will always be the same length with the pattern:
One letter, 2 number, one letter, 2 numbers pattern (C05F78)
Any thing in the string after that is what I would like to remove.
that's it
$x=array(
"The.Test.String.A01Y18.123h.WIB-DI.DO5.1.K.314-ECO",
"The.Regex.F05P78.123h.WIB-DI.DO5.1.K.314-EYT",
"Word.C05F78.342T.DSW-RF.EF5.2.F.342-DDF"
);
for ($i=0, $tmp_count=count($x); $i<$tmp_count; ++$i) {
echo str_replace(".", " ", preg_replace("/^(.+?)([a-z]{1}[0-9]{2}[a-z]{1}[0-9]{2})\..+$/i", "\\1\\2", $x[$i]))."<br />";
}
Using this regular expression should work, replacing each of your strings with the first capturing group:
^((?:\w+\.)+\w\d{2}\w\d{2}).*
See demo at http://regex101.com/r/fR3pM6
This is valid too:
preg_match("\.*[\w\d]{6}", stringVariable)
.* for all digits atleast we found a composition of letters and words of 6 characters ([\w\d]{6})
Result:
Match 1: The.Test.Stsrisng.A01Y18
Match 2: The.Regex.F05P78
Match 3: Word.C05F78
Related
I have a value like this 73b6424b. I want to split value into two parts. Like 73b6 and 424b. Then the two split value want to reverse. Like 424b and 73b6. And concatenate this two value like this 424b73b6. I have already done this like way
$substr_device_value = 73b6424b;
$first_value = substr($substr_device_value,0,4);
$second_value = substr($substr_device_value,4,8);
$final_value = $second_value.$first_value;
I am searching more than easy way what I have done. Is it possible?? If yes then approach please
You may use
preg_replace('~^(.{4})(.{4})$~', '$2$1', $s)
See the regex demo
Details
^ - matches the string start position
(.{4}) - captures any 4 chars into Group 1 ($1)
(.{4}) - captures any 4 chars into Group 2 ($2)
$ - end of string.
The '$2$1' replacement pattern swaps the values.
NOTE: If you want to pre-validate the data before swapping, you may replace . pattern with a more specific one, say, \w to only match word chars, or [[:alnum:]] to only match alphanumeric chars, or [0-9a-z] if you plan to only match strings containing digits and lowercase ASCII letters.
$txt = "toto1 555.4545.555.999.7465.432.674";
$rgx = "/([\w]+)\s([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/";
preg_match($rgx, $txt, $res);
var_dump($res);
I would like to simplify this pattern by avoiding repeating "([0-9]+)" because i don't know how many they are.
Any one can say me how ?
Here is a direct answer to the question, as you have stated it:
/[\w]+\s[0-9]+(?:\.[0-9]+)+/
However, note that I have removed all of the numbered capture groups. This could be problematic, depending on what you're actually trying to achieve.
It is not possible to "count" with capture groups in regular expressions, so you would need to write some other code (i.e. not just one match, with one regex, and using back-references) to deal with this if you wish to run any queries like "What digits appear after the fifth "."?"
There are two ways you can do this. If you just need to verify that the string matches the pattern, this regex will do the job: \w+\s(?:[0-9]+\.?)+
However, if you need to split the string in to it's component parts (in my interpretation, the beginning word followed by the sequence of decimal separated numbers), then you could use this pattern: (\w+)\s((?:[0-9]+\.?)+)
The second pattern will return the beginning word, toto1 in group 1, followed by the decimal separated numbers in group 2 555.4545.555.999.7465.432.674 which you could then split in PHP if required: $sequence = explode('.', $matches[2]);
What you need can be obtained with a preg_split with a regex matching 1 or more whitespaces or dots:
$txt = "toto1 555.4545.555.999.7465.432.674";
$rgx = '/[\s.]+/';
$res = preg_split($rgx, $txt);
print_r($res);
See the PHP demo
If you need a regex approach, you can use a \G based regex with preg_match_all:
'~(?|([\w]+)|(?!\A)\G[\s.]*([0-9]+))~'
See the regex demo and a PHP demo:
$txt = "toto1 555.4545.555.999.7465.432.674";
$rgx = '~(?|(\w+)|(?!\A)\G[\s.]*([0-9]+))~';
preg_match_all($rgx, $txt, $res);
print_r($res[1]);
Pattern details:
The (?|...) is a branch reset group to reset group IDs in all the branches
(\w+) - Group 1 matches 1+ word chars
| - or (then goes Branch 2)
(?!\A)\G - the end of the previous successful match
[\s.]* - zero or more whitespaces or dots
([0-9]+) - Group 1 (again!) matching 1 or more digits.
I have many Strings looking like this:
QR-DF-6549-1 and QR-DF-6549
I want to get these parts of the strings:
DF-6549
Edit:
So I also want to get rid of the "-1" at the end, in case it exists.
How can I do this with php? I know substr but I am a bit lost at this one.
Thank you very much!
A regular expression is probably the best way given your sample data
// ^ start matching at start of string
// [A-Z]{2}- must start with two capital letters and a dash
// ( we want to capture everything that follows
// [A-Z]{2}- next part must start with two capital letters and a dash
// \d+ a sequence of one or more digits
// ) end the capture - this will be index 1 in the $match array allowed
if (preg_match('/^[A-Z]{2}-([A-Z]{2}-\d+)/', $str, $match)) {
$data=$match[1];
}
I need 2 groups captured: 1-expr (can be empty); 2-essi
see code below
$s = 'regular expr<span>essi</span>on contains';
function my_func($matches){
//I need 2 groups captured
//$matches[1] - "expr" (see $s before span) - can be empty, but I still need to capture it
//$matches[2] - "essi" (between spans)
}
$pattern = "???";
echo preg_replace_callback($pattern, my_func, $s);
$pattern = "~(\w*)<span>(\w+)</span>~";
This should do the trick.
If the second group should be able to match empty strings as well, replace the + by another *. Note that \w will match letters, digits and underscores. If that is too much or insufficient, replace it by an appropriate character class.
One more thing: I think the syntax for preg_replace_callback requires you to hand in the function name as a string.
I have a string that contains 5 words. In the string one of the words is a Ham Radio Call Sign and can be anyone of the thousands of call signs in the US. In order to extract the Call Sign from the string I need to utilize the below pattern. The Call Sign I need to extract can be in any of the 5 positions in the string. The number is never the first character and the number is never the last character. The string is actually put together from an Array since it is originally read from a text file.
$string = $word[1] $word[2] $word[3] etc....
So the search can be either done on the whole string or each piece of the array.
Patterns:
1 Number and 3 Letters Example: AB4C A4BC
1 Number and 4 Letters Example: A4BCD
1 Number and 5 Letters Example: AB4CDE
I have tried everything I can think of and search till I cant search no more. I am sure I am over thinking this.
A two-step regular expression like this would do it:
$str = "hello A4AB there BC5AD";
$signs = array();
preg_match_all('/[A-Z][A-Z\d]{1,3}[A-Z]/', $str, $possible_signs);
foreach($possible_signs[0] as $possible_sign)
if (preg_match('/^\D+\d\D+$/', $possible_sign))
array_push($signs, $possible_sign);
print_r($signs); //Array ([0] => A4AB [1] => BC5AD)
Explanation
This is a regular expression approach, using two patterns. I don't think it could be done with one and still satisfy the exact requirements of the matching rules.
The first pattern enforces the following requirements:
substring starts and ends with a capital letter
substring contains only other capital letters or numbers between the first and last letter
substring is, overall, not more than 6 characters long
What I can't do in that same pattern, for complex REGEX reasons I won't go into (unless someone knows a way and can correct me), is enforce that only one number is contained.
#jeroen's answer does enforce this in a single pattern, but in turn does not enforce the correct length of the substring. Either way, we need a second pattern.
So after grabbing the initial matches, we loop over the results. We then apply each to a second pattern that enforces simply that there is only one number in the substring.
If so, we green-light the substring and it's added to the $signs array.
Hope this helps.
It depends on what the other words can contain, but you could use a regular expression like:
#\b[a-z]+\d[a-z]+\b#i
^ case insensitive
^^ a word boundary
^^^^^^ One or more letters
^^ One number
You can make it more restrictive by using {1,3} instead of + for the letters so that you have a sequence of 1 to 3 letters.
The complete expression would be something like:
$success = preg_match('#\b[a-z]+\d[a-z]+\b#i', $input_string, $matches);
where $matches[0] will contain the matched value, see the manual.