user4023870
user4023870

Reputation:

How to match two patterns with a space between them in JavaScript?

I know how to match one pattern using JavaScript:

var pattern = somePattern

    if (!pattern.test(email)) { //do something }

but what if I have to match 2 patterns with a space between them so if I have this:

word1 word2

word1 should match pattern1
word2 should match pattern2
a space should be between them

How can I achieve this using JavaScript?

word1word2 is refused (even if they much pattern1 and pattern2 in order, because of the lack of space)

word1 should be an IP; word2 should be a number

Some examples:

172.30.10.10 10 (acceptable)
172.30.10.1010 (not acceptable)
10 10 (not acceptable)
10 172.30.10.10 (not acceptable)

Upvotes: 4

Views: 72

Answers (4)

kornieff
kornieff

Reputation: 2557

A bit more compact and complete solution:

var ipNum = "\\d{1,3}";
var ip    = "(" + ipNum + "\\.){3}" + ipNum;
var num   = "\\d+";

var ipRE  = new RegExp("^\\s*" + ip + "\\s+" + ipNum + "\\s*$");

console.log(ipRE.test(" 172.30.10.10   10   ")); // true

Upvotes: 0

Brian S
Brian S

Reputation: 5056

Building on Joe Frambach's answer, you could perform some sanity checking on the input:

function combinePatterns(pattern1, pattern2, options) {
    if (pattern1.constructor != RegExp || pattern2.constructor != RegExp) {
        throw '`pattern1` and `pattern2` must be RegExp objects';
    }

    var pattern1_str = pattern1.source;
    var pattern2_str = pattern2.source;
    options = options || {};

    // Ensure combining the patterns makes something sensible
    var p1_endOfLine, p2_startOfLine;
    if (pattern1_str.lastIndexOf('$') == pattern1_str.length - 1) {
        p1_endOfLine = true;
        if (options.stripBadDelimiters || options.swapBadDelimiters) {
            pattern1_str = pattern1_str.substr(0, pattern1_str.length - 1);
        }

        if (options.swapBadDelimiters
            && pattern2_str.lastIndexOf('$') != pattern2_str.length - 1) {
            pattern2_str += '$';
        }
    }

    if (pattern2_str.indexOf('^') == 0) {
        p2_startOfLine = true;
        if (options.stripBadDelimiters || options.swapBadDelimiters) {
            pattern2_str = pattern2_str.substr(1);
        }

        if (options.swapBadDelimiters && pattern1_str.indexOf('^') != 0) {
            pattern1_str = '^' + pattern1_str;
        }
    }

    if (p1_endOfLine && p2_startOfLine && options.swapPatterns) {
        var tmp = pattern1_str;
        pattern1_str = pattern2_str;
        pattern2_str = tmp;
    }

    return new RegExp(pattern1_str + ' ' + pattern2_str);
}

var first = combinePatterns(/abc/, /123/);
var second = combinePatterns(/abc$/, /^123/);
var third = combinePatterns(/abc$/, /^123/, { stripBadDelimiters: true });
var fourth = combinePatterns(/abc$/, /^123/, { swapBadDelimiters: true });
var fifth = combinePatterns(/abc$/, /^123/, { swapPatterns: true });

// first = /abc 123/
// second = /abc$ ^123/
// third = /abc 123/
// fourth = /^abc 123$/
// fourth = /^123 abc$/

This isn't the end-all be-all of what you can do to help ensure your input produces the desired output, but it should illustrate the sorts of possibilities that are open to you when reconstructing the regex pattern in this fashion.

Upvotes: 0

Moob
Moob

Reputation: 16184

Combine it into a single pattern:

var pattern = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+\d{1,}/;
var test= '172.30.10.10 10';
var matched = test.match(pattern);

http://regex101.com/r/kU9cN3/3

UPDATE further to Brian's comment. If they need to be coded as separate patterns you can do as follows. This may be useful if you want to re-use patterns or make other combinations.

var ip = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
    number = /\d{1,}/,
    combinedRegExp = new RegExp(ip.source+' '+number.source);
var testString = '172.30.10.10 10';
var result = combinedRegExp.test(testString);
console.log(result);//true

http://jsfiddle.net/7Lrsxov8/

Upvotes: 1

000
000

Reputation: 27247

According to the documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source

The RegExp object has a source property, which returns a string representation of the regex.

Here's an example.

var validName = /\w+ \w+/
var validEmail = /[^@ ]+@.+\..+/
var combined = new RegExp(validName.source + ' ' + validEmail.source);

console.log(combined.test('John Doe [email protected]'));
// outputs true

console.log(combined.test('John Doe bademail@'));
// outputs false

However, keep in mind that this solution will NOT work if the regexes include boundary markers like $ and ^.

Upvotes: 2

Related Questions