开发者

php preg_match nightmare

I just cant get my head around regex, any help appreciated !

I have plenty of string data which may or may not contain the strings "1/10" or "2/10" or "2/18" etc. Basically, both the numerators and denominators could vary. And to make things more complex, some of the data entry operators may have put a space anywhere between the numerators and denominators !! So my inputs could be : "x/y" or "x / y" or "x/ y" or "x /y" or "x/y " .... and probably more combos :(

In any开发者_如何学Go of these cases, I wish to identify if x and y are numbers, and if there is a "/" slash between them. Am hopeless at regex, please help

Am coding in php and I guess preg_match is what needs to be used. Thanks for reading.


$pattern = "%(\d+) */ *(\d+)%";

$test = array(
    'half is 1/2',
    '13/100 is your score',
    'only 23 /90 passed',
    'no idea here:7/ 123',
    '24 / 25',
    '1a/2b'
);

foreach($test as $t){
    if(preg_match($pattern, $t, $matches))
        echo "PASS: n:$matches[1], d:$matches[2]\n";
    else
        echo "FAIL: $t\n";
}

outputs:

PASS: n:1, d:2
PASS: n:13, d:100
PASS: n:23, d:90
PASS: n:7, d:123
PASS: n:24, d:25
FAIL: 1a/2b


if(preg_match('~^[0-9]+\s*/\s*[0-9]+$~',trim($subject))) {
  // valid
} 


if(preg_match('@^\s?[0-9]+\s?\/\s?[0-9]+\s?$@', $s) {
     ...
}


I think you should avoid regexp at any cost. A couple of cases you should(could):

  • You are an expert in regexp. If you are you, then probably you should use regexp because it probably is going to be faster and terser code. Although the readability is going to suck in my opinion.
  • You need to improve performance.

Otherwise my advice is to not use it!

In any of these cases, I wish to identify if x and y are numbers, and if there is a "/" slash between them. Am hopeless at regex, please help

How to solve your problem:

<?php

class Verify {
    public static function numbers($str) {
        $explode = explode("/", $str);

        foreach($explode as $elm) {
            if (!filter_var($elm, FILTER_VALIDATE_INT)) {
                return false;
            }
        }
        return true;
    }
}
class StackTest extends PHPUnit_Framework_TestCase {
    public function testBothPartsAreNumbers() {
        $array = array(
            "1/2",
            "1 / 2",
            "1/ 2",
            "1 /2"
        );
        foreach($array as $elm) {
            $this->assertTrue(Verify::numbers($elm));
        }
    }

    public function testOneOfThemMightBeNotANumber() {
        $array = array(
            "1/a",
            "a/1",
            "1 / a",
            "b/2",
            "b/a",
            "1/2.1",
        );
        foreach($array as $elm) {
            $this->assertFalse(Verify::numbers($elm));
        }
    }
}
?>

alfred@alfred-laptop:~/php/stackoverflow/4916920$ php -v
PHP 5.3.3-1ubuntu9.3 with Suhosin-Patch (cli) (built: Jan 12 2011 16:08:14) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

# We need at least PHP5.2 for filter.

alfred@alfred-laptop:~/php/stackoverflow/4916920$ phpunit NumberTest.php 
PHPUnit 3.5.10 by Sebastian Bergmann.

..

Time: 0 seconds, Memory: 3.50Mb

OK (2 tests, 10 assertions)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜