Regex Testing for URLs

Compares the current regex (used in Minecraft 1.5.1 for URL matching in the Chat GUI) to a proposed replacement.

by techbrew

HTML

<h1>URL Matching Tests</h1>

<h3>Regex 1: <span class="regex" id="heading1"></span></h3>

<h3>Regex 2: <span class="regex" id="heading2"></span></h3> 
<div id="info"></div>

<h4>Tests which should match the URL:</h4>

<table id="posresults">
    <tr>
        <th></th>
        <th>Test URL</th>
        <th>Regex 1</th>
        <th>Regex 2</th>
    </tr>
</table>

<h4>Tests which should not match a bad URL:</h4>

<table id="negresults">
    <tr>
        <th></th>
        <th>Test URL</th>
        <th>Regex 1</th>
        <th>Regex 2</th>
    </tr>
</table>
<hr>

CSS

body {
    font-family:'Arial'
}
th {
    padding-right:10px;
    overflow: hidden;
}
#info {
    margin-bottom:10px;
}
.regex {
    color:blue
}
.test {
    text-align:right;
    padding-right:10px;
}
.passed {
    color:#222;
}
.failed {
    color:red;
}

JavaScript

// Regex used in Minecraft 1.5.1 to make URLs clickable in chat
var regex1 = "^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$";

// Proposed replacement
var regex2 = '^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[,;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$'; // hash

var runTests = function (r1, r2) {

    document.getElementById('heading1').innerHTML = r1;
    document.getElementById('heading2').innerHTML = r2;

    var aRegex1, aRegex2;
    try {
        aRegex1 = new RegExp(r1);
        aRegex2 = new RegExp(r2);

        var posTests = [];
        posTests = posTests.concat(generateTests("mojang.nl"));
        posTests = posTests.concat(generateTests("mojang.com"));
        posTests = posTests.concat(generateTests("mojang.info"));
        posTests = posTests.concat(generateTests("107.21.219.224"));
        runTestSet(posTests, aRegex1, aRegex2, true);

        var negTests = [];
        negTests = negTests.concat(generateTests("mojang.x"));
        negTests = negTests.concat(generateTests("1.2.3"));
        runTestSet(negTests, aRegex1, aRegex2, false);

        document.getElementById('info').innerHTML =
            "Regex1 failed tests: " + fails1 + " out of " + count + "<br>" +
            "Regex2 failed tests: " + fails2 + " out of " + count + "<br><br>" +
            "Tests run on: " + new Date();

    } catch (error) {
        document.getElementById('info').innerHTML = error;
    }
}

var runTestSet = function (tests, aRegex1, aRegex2, expected) {
    tests.map(function (aTest) {
        var match1 = aRegex1.exec(aTest);
        var match2 = aRegex2.exec(aTest);
        showResult(aTest, match1, match2, expected);
    });
}

var generateTests = function (host) {
    var hosts = [host];
    if (isNaN(host.substring(0, 1))) {
        hosts = [host, "www." + host,...