Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to validate a URL using a Regex with PHP. I need a pattern that considers valid:

Any other is not valid, so you can't have ssh://, a .com domain, etc.

I tried the following pattern:

/(((http|ftp|https):\/{2})+(([0-9a-z_-]+\.)+(pf)(:[0-9]+)?((\/([~0-9a-zA-Z\#\+\%@\.\/_-]+))?(\?[0-9a-zA-Z\+\%@\/&\[\];=_-]+)?)?))\b/imuS

but I've lost many hours (and hairs) trying to make it work the way I need it to work.

Any suggestion is appreciated.

share|improve this question
    
Use php.net/parse_url, it tells many information about an url, including scheme, host.. –  Andrew Feb 24 at 9:14

5 Answers 5

There is parse_url function in php.

Then it will be much easier to validate the scheme and host of the result of parse_url.

share|improve this answer
    
Problem is it failed in some cases: I tried it but it isn't perfect –  3000 Feb 24 at 9:43
    
@3000 It failed means that is not a well formed URL. –  xdazz Feb 24 at 9:54
1  
it means that parse_url is not perfect: it doesn't work if the protocol is not specified. The user can submit domain.pf too. –  3000 Feb 24 at 10:01

Try this

/((https?|ftp):\/\/.)?(www\.)?[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*\.pf/i

I am not sure whether this is the best solution.

share|improve this answer
    
Unfortunately not working. –  3000 Feb 24 at 10:08
    
which url did this expression fail? Can u please share? If you want to match _ and -. you may add it to character class. –  Mobin Skariya Feb 24 at 10:16
    
My suspect is JS and PHP regexp aren't the same: maybe this works with JavaScript. –  3000 Feb 24 at 10:21

As per your need, you have to try this

 <?php
        $regex = "((https?|ftp)\:\/\/)?"; // SCHEME
        $regex .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?"; // User and Pass
        $regex .= "([a-z0-9-.]*)\.([a-z]{2,4})"; // Host or IP
        $regex .= "(\:[0-9]{2,5})?"; // Port
        $regex .= "(\/([a-z0-9+\$_-]\.?)+)*\/?"; // Path
        $regex .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?"; // GET Query
        $regex .= "(#[a-z_.-][a-z0-9+\$_.-]*)?"; // Anchor
    ?>
share|improve this answer
2  
Have you even read the question? –  Second Rikudo Feb 24 at 9:21

This is a better way of doing what you want, granted it doesn't use regular expressions, but it is easier to maintain and uses native php functions for that reason:

<?php
function isValidPFurl($url) {
    if (strpos($url, "://" ) === false) {
        $url = 'http://' . $url;
    }
    $valid = filter_var($url, FILTER_VALIDATE_URL);
    if ($valid !== false) {
        $parsed = parse_url($valid);
        $host = $parsed['host'];
        $scheme = $parsed['scheme'];
        $valid = false;
        switch($scheme) {
            case 'ftp':
            case 'http':
            case 'https':
                $p = explode(".", $host);
                if ($p[sizeof($p) - 1] == 'pf') {
                    $valid = true;
                }
                break;
            default:
                $valid = false;
        }
    }
    return $valid;
}

$testUrls = array(
"http://example.pf/",
"example.pf",
"www.example.pf",
"ftp://example.pf",
"https://example.pf",
"ssl://example.pf"
);
foreach ($testUrls as $url) {
    echo "is $url valid? ", (int) isValidPFurl($url), "\n";
}
share|improve this answer
    
This doesn't solve the problem for www.domain.pf and domain.pf (they return 0), while it is ok for http://... –  3000 Feb 24 at 9:52
    
I've fixed that now - if no scheme/protocol is in the url, it'll prepend "http://" for parse_url –  kguest Feb 24 at 13:48
    
Hehe, I can't explain why but this solution is not acceptable. I thank you very much for the effort, anyway. :-) –  3000 Feb 24 at 15:26

^((http|ftp)[s]?://)?([\w-/.]+)(.pf)([\w-/.\&\%\$+\?]+)?$

Handles everything requested, unless I interpret the question wrong. Test here: http://www.cuneytyilmaz.com/prog/jrx/ Please, do tick case insensitive.

to implement in php use /^((http|ftp)[s]?://)?([\w-/.]+)(.pf)([\w-/.\&\%\$+\?]+)?$/i

share|improve this answer
    
Thanks, somehow the escaped chars became unescaped when posting :) –  Digitalis Feb 24 at 9:23
    
Unfortunately not working. –  3000 Feb 24 at 10:08
    
In what sense, could you please be more specific? I could have it fixed in a matter of minutes I reckon –  Digitalis Feb 24 at 22:59
    
I updated my answer since I discovered I overlooked some details in the requirements. You can retest the regex and see that it will work. Should you need to add more special characters, please submit them here and I'll update the solution. –  Digitalis Feb 24 at 23:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.