PHP: Best method to extract numbers from a string [duplicate] - php

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
a simple function for return number from string in php
What's the best/most efficient method to extract a specific set of numbers from a string? For example: I want to get the set of numbers immediately after Case# in sring "blah blah Case#004522 blah blah". I imagine the number of numeric characters after Case# will always be the same but I would like the code to not make that assumption as I have been.
So far I have been using a strpos method to locate Case# and then pull a specific number of characters afterwords using substr. I just feel like this is clunky. Maybe preg_match would be more effective or simplified?
$text = "blah blah Case#004552 blah blah";
$find = strpos($text,'Case#');
if ( $find )
$numbers = substr($text, $find+5, 6);

You can make use of regular expressions to first match your pattern of characters (Case#) and then you expect to match numbers only (digits), that is \d in PCRE (Demo):
$numbers = preg_match("/Case#(\d+)/", $text, $matches)
? (int)$matches[1]
: NULL
;
unset($matches);
For multiple (integer) matches at once:
$numbers = preg_match_all("/Case#(\d+)/", $text, $matches)
? array_map('intval', $matches[1])
: NULL
;
unset($matches);

You can locate it as you do it already, and then scan for the number (Demo):
$find = strpos($text, 'Case#');
sscanf(substr($text, $find), 'Case#%d', $numbers);

Use PHP's preg_match and following regex:
(?<=case#)[0-9]+
You can test # http://regexr.com?31jdv

The simplest solution is
if (preg_match('/Case#\s*(\d+)/i', $test, $m)) {
$numbers = $m[1];
}

Related

How to make preg_replace not hungry? [duplicate]

This question already has answers here:
What is the difference between .*? and .* regular expressions?
(3 answers)
Closed 4 years ago.
I have a string:
$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';
now i need to get substring for setted language.
$placeholder = '{:en}';
$lang_content = preg_replace('/(.*)'.preg_quote($placeholder).'(.*)'.preg_quote('{:}').'(.*)/sm', '\2', $str);
in case of value for placeholder {:en} i get Helo world as value for $lang_content, it works fine, but in case {:de} i get Hallo Welt{:}{:en}Helo world.
How can it be fixed? thanx!
You need to make the regex lazy by adding a ? in the second capture.
$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';
$placeholder = '{:de}';
$lang_content = preg_replace('/(.*)'.preg_quote($placeholder).'(.*?)'.preg_quote('{:}').'(.*)/sm', '\2', $str);
echo $lang_content; // Hallo Welt
https://3v4l.org/m6AGF
An optional method would be to use preg_match to get an associative array.
$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';
preg_match_all("/\{:(.*?)}(.*?)\{/", $str, $matches);
$matches = array_combine($matches[1], $matches[2]);
var_dump($matches);
echo $matches["de"]; // Hallo Welt
https://3v4l.org/ELB2B
With the Ungreedy flag (U).
You can update the flags at the end of your regex from /sm to /smU for the result to stop at the next occurrence of {:} in the string and not at the last one.
If the string is to contain several occurrences, maybe you can also add the global (g) flag so the regex doesn't stop after the first one.
You can test it here: https://regex101.com/r/4XSPoz/3
By the way, it seems that your are using preg_replace as a way to find a substring and don't actually need to replace it in the result, maybe you should use preg_match instead.

Php get specific word of string

What is the php function to extract only the word Duitsland from the following string /Duitsland|/groepsreizen fietsen|Stars/1.
I tried everything but dit not find the right method.
http://php.net/manual/de/function.str-replace.php
$result= str_replace("Duitsland", "", "/Duitsland|/groepsreizen fietsen|Stars/1");
Result: "/|/groepsreizen fietsen|Stars/1"
There is multiple way to do this work. One way is using regex. Use regex in preg_match() to finding specific word of string.
$str = "/Duitsland|/groepsreizen fietsen|Stars/1";
preg_match("/[^|\/]+/", $str, $match);
echo $match[0];
You can test it in demo
with strpos function find require o/p
$haystack = '/Duitsland|/groepsreizen fietsen|Stars/1';
$needle = 'Duitsland';
if (strpos($haystack,$needle) !== false) {
echo $needle;
}
I think this is what you're looking for:
(this code does not need to know what is the word before, it just seeks the first (as long as possible) word in the string)
<?php
$str = "/Duitsland|/groepsreizen fietsen|Stars/1";
preg_match("/\w+/i", $str, $matches);
$first_word = array_shift($matches);
echo $first_word;
It will work no matter how many non-letter symbols there are before that word, i.e. it's not dependent on any fixed-count other characters.
Demo: http://ideone.com/GX8IT6

Regular Expression - Negation String + OR

I need to match string that are not 11111 OR 22222 (EXACT)
<?php
$string = 'STRING'
$pattern = '#PATTER#' // what I have to find
echo preg_match($pattern, $string) ? 'match' : 'no match';
Cases:
$string = '33333';// match
$string = '222222';// match
$string = '11111';// no match
$string = '22222';// no match
I tried many patters that I google and none of them work.
NOTE: It has to be pure REGEX and NOT negating the function preg_match
How about:
^(?!11111$|22222$).*
test: https://regex101.com/r/wU7yO0/1
How about this:
^(|.|..|...|....|(?!11111|22222).....|......+)$
The basic idea is: All strings of length 0-4 and 6+ are fine. The string of length 5 must not be 11111 or 22222.
Edit: And to compress the length a bit (but make it less readable IMO):
^(.{0,4}|(?!11111|22222).{5}|.{6}.*)$

How to extract a collection of numbers from a string?

I need to extract a project number out of a string. If the project number was fixed it would have been easy, however it can be either P.XXXXX, P XXXXX or PXXXXX.
Is there a simple function like preg_match that I could use? If so, what would my regular expression be?
There is indeed - if this is part of a larger string e.g. "The project (P.12345) is nearly done", you can use:
preg_match('/P[. ]?(\d{5})/',$str,$match);
$pnumber = $match[1];
Otherwise, if the string will always just be the P.12345 string, you can use:
preg_match('/\d{5}$/',$str,$match);
$pnumber = $match[0];
Though you may prefer the more explicit match of the top example.
Try this:
if (preg_match('#P[. ]?(\d{5})#', $project_number, $matches) {
$project_version = $matches[1];
}
Debuggex Demo
You said that project number is 4 of 5 digit length, so:
preg_match('/P[. ]?(\d{4,5})/', $tring, $m);
$project_number = $m[1];
Assuming you want to extract the XXXXX from the string and XXXXX are all integers, you can use the following.
preg_replace("/[^0-9]/", "", $string);
You can use the ^ or caret character inside square brackets to negate the expression. So in this instance it will replace anything that isn't a number with nothing.
I would use this kind of regex : /.*P[ .]?(\d+).*/
Here is a few test lines :
$string = 'This is the P123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
$string = 'This is the P.123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
$string = 'This is the P 123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
use explode() function to split those

preg replace complete word using partial patterns in PHP

I am using preg_replace($oldWords, $newWords, $string); to replace an array of words.
I wish to replace all words starting with foo into hello, and all words starting with bar into world
i.e foo123 should change to hello , foobar should change to hello, barx5 should change to world, etc.
If my arrays are defined as:
$oldWords = array('/foo/', '/bar/');
$newWords = array('hello', 'world');
then foo123 changes to hello123 and not hello. similarly barx5 changes to worldx5 and not world
How do I replace the complete matched word?
Thanks.
This is actually pretty simple if you understand regex, as well as how preg_replace works.
Firstly, your replacement arrays are incorrectly formed. What is:
$oldWords = array('\foo\', '\bar\');
Should instead be:
$oldWords = array('/foo/', '/bar/');
As the backslash in php escapes the character after it, meaning your strings were getting turned into non-strings, and it was messing up the rest of your code.
As to your actual question, however, you can achieve the desired effect with this:
$oldWords = array('/foo\w*/', '/bar\w*/');
\w matches any word character, while * is a quantifier either meaning 0 or any number of matches.
Adding in those two items will cause the regex to match any string with foo and x number of word-characters directly after it, which is what preg_replace then replaces; the match.
one way to do it is to loop through the array checking each word, since we are only checking the first three letters I would use a substr() instead of a regex because regex functions are slower.
foreach( $oldWords as $word ) {
$newWord = substr( $word, 0, 2 );
if( $newWord === 'foo' ) {
$word = 'hello';
}
else if( $newWord === 'bar' ) {
$word = 'world';
}
};

Categories