Find the position of the first occurrence of any number in string
Asked Answered
T

5

13

Can someone help me with algorithm for finding the position of the first occurrence of any number in a string?

The code I found on the web does not work:

function my_offset($text){
    preg_match('/^[^\-]*-\D*/', $text, $m);
    return strlen($m[0]);
}
echo my_offset('[HorribleSubs] Bleach - 311 [720p].mkv');
Terreverte answered 21/9, 2011 at 6:46 Comment(2)
try preg_match('/[\d]+/', $text, $m);Broderic
Also, I find it handy to use an online "python regex repl" to test out and debug regex expressions. For example: pythex.orgIsadora
V
15
function my_ofset($text){
    preg_match('/^\D*(?=\d)/', $text, $m);
    return isset($m[0]) ? strlen($m[0]) : false;
}

should work for this. The original code required a - to come before the first number, perhaps that was the problem?

Vicinal answered 21/9, 2011 at 6:51 Comment(5)
if there is no number in string it returns length of original string?Terreverte
@gašper: Right. Can be fixed, but Stanislav's solution is much better.Vicinal
Why is his solution better? if there is no number in string it returns me 1 (with his algorithm). if i use yours it returns me something logical (string length).Terreverte
@gašper I've edited mine. If there's no number it now returns string length as well. I guess it's better because a) it searches exactly for numbers, not for non-numbers and b) it utilizes preg_match built-in feature which is always better than reinventing a bike. I hope Tim agrees with me :-)Mechanical
@gašper: Well, my solution is kind of bent-over backwards (count the number of non-digits until the first digit). Also, thinking about it, I expect my solution to require an additional check whether there has been a match at all. I'm not a PHP programmer, so I'm building that code upon snippets created by RegexBuddy using my regex.Vicinal
S
28

The built-in PHP function strcspn() will do the same as the function in Stanislav Shabalin's answer when used like so:

strcspn( $str , '0123456789' )

Examples:

echo strcspn( 'That will be $2.95 with a coupon.' , '0123456789' ); // 14
echo strcspn( '12 people said yes'                , '0123456789' ); // 0
echo strcspn( 'You are number one!'               , '0123456789' ); // 19

HTH

Sheaff answered 30/3, 2018 at 17:22 Comment(2)
I bet that this is about 20 times faster than any regex solutionBinge
note: it works fine with non-latin text, but then don't use mb_substrDepositary
M
20
function my_offset($text) {
    preg_match('/\d/', $text, $m, PREG_OFFSET_CAPTURE);
    if (sizeof($m))
        return $m[0][1]; // 24 in your example

    // return anything you need for the case when there's no numbers in the string
    return strlen($text);
}
Mechanical answered 21/9, 2011 at 6:53 Comment(1)
Makes more sense. I (and RegexBuddy) didn't know about PREG_OFFSET_CAPTURE :)Vicinal
V
15
function my_ofset($text){
    preg_match('/^\D*(?=\d)/', $text, $m);
    return isset($m[0]) ? strlen($m[0]) : false;
}

should work for this. The original code required a - to come before the first number, perhaps that was the problem?

Vicinal answered 21/9, 2011 at 6:51 Comment(5)
if there is no number in string it returns length of original string?Terreverte
@gašper: Right. Can be fixed, but Stanislav's solution is much better.Vicinal
Why is his solution better? if there is no number in string it returns me 1 (with his algorithm). if i use yours it returns me something logical (string length).Terreverte
@gašper I've edited mine. If there's no number it now returns string length as well. I guess it's better because a) it searches exactly for numbers, not for non-numbers and b) it utilizes preg_match built-in feature which is always better than reinventing a bike. I hope Tim agrees with me :-)Mechanical
@gašper: Well, my solution is kind of bent-over backwards (count the number of non-digits until the first digit). Also, thinking about it, I expect my solution to require an additional check whether there has been a match at all. I'm not a PHP programmer, so I'm building that code upon snippets created by RegexBuddy using my regex.Vicinal
P
0

I can do regular expressions but I have to go into an altered state to remember what it does after I've coded it.

Here is a simple PHP function you can use...

function findFirstNum($myString) {

    $slength = strlen($myString);

    for ($index = 0;  $index < $slength; $index++)
    {
        $char = substr($myString, $index, 1);

        if (is_numeric($char))
        {
            return $index;
        }
    }

    return 0;  //no numbers found
}
Pipkin answered 7/10, 2017 at 21:53 Comment(0)
A
0

Problem

Find the first occurring number in a string

Solution

Here is a non regex solution in javascript

var findFirstNum = function(str) {
    let i = 0;
    let result = "";
    let value;
    while (i<str.length) {
      if(!isNaN(parseInt(str[i]))) {
        if (str[i-1] === "-") {
          result = "-";
        }
        while (!isNaN(parseInt(str[i])) && i<str.length) {
          result = result + str[i];
          i++;
        }
        break;
      }
      i++;
    }
    return parseInt(result);  
};

Example Input

findFirstNum("words and -987 555");

Output

-987
Afra answered 26/8, 2019 at 6:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.