简体   繁体   中英

Regex to find a regular expression flags and search pattern

Having a string like:

"/some regex/gi"

How can I get an array with the search pattern ( "some regex" ) and flags ( "gi" )?

I tried to use match function:

> "/some regex/gi".match("/(.*)/([a-z]+)")
[ '/some regex/gi',
  'some regex',
  'gi',
  index: 0,
  input: '/some regex/gi' ]

However, this fails for regular expressions without flags (returns null ) and probably for other more complex regular expressions.

Examples:

"without flags" // => ["without flags", "without flags", ...]
"/with flags/gi" // => ["/with flags/gi", "with flags", "gi", ...]
"/with\/slashes\//gi" // => ["/with\/slashes\//gi", "with\/slashes\/", "gi", ...]
"/with \/some\/(.*)regex/gi" // => ["/with \/some\/(.*)regex/gi", "with \/some\/(.*)regex", "gi", ...]

The order in array is not important, however, the positions of search patter and flags should be the same.


Actually, I want to take a string and parse it. After getting the search pattern and flags I want to pass them to new RegExp(searchPattern, flags) -- then I have a real regular expression.

For my input I want to accept strings with and without slashes. No slashes (actually no slash at the begining -- first char) indicate that there are no flags.

So, for "/hi/gi" , we will have re = new RegExp("hi", "gi") . Also see the following examples:

"/singlehash" => new RegExp("/singlehash", undefined)
"single/hash" => new RegExp("single/hash", undefined)
"/hi/" => new RegExp("hi", undefined)
"hi" => new RegExp("hi", undefined)
"/hi\/slash/" => new RegExp("hi\/slash", undefined)
"/hi\/slash/gi" => new RegExp("hi\/slash", "gi")
"/^dummy.*[a-z]$/flags" => new RegExp("^dummy.*[a-z]$", "flags")

I created the following little script that should not output any errors:

var obj = {
    "without flags": new RegExp("without flags"),
    "/something/gi": new RegExp("something", "gi"),
    "/with\/slashes\//gi": new RegExp("with\/slashes\/", "gi"),
    "/with \/some\/(.*)regex/gi": new RegExp("with \/some\/(.*)regex", "gi"),
    "/^dummy.*[a-z]$/gmi": new RegExp("^dummy.*[a-z]$", "gmi"),
    "raw input": new RegExp("raw input"),
    "/singlehash": new RegExp("/singlehash"),
    "single/hash": new RegExp("single/hash")
};

var re = /^((?:\/(.*)\/(.*)|.*))$/;

try {
    for (var s in obj) {
        var c = obj[s];
        var m = s.match(re);
        if (m === null) {
            return console.error("null result for" + s);
        }
        console.log("> Input: " + s);
        console.log("  Pattern: " + m[1]);
        console.log("  Flags: " + m[2]);
        console.log("  Match array: ", m);
        var r = new RegExp(m[1], m[2]);
        if (r.toString() !== c.toString()) {
            console.error("Incorrect parsing for: " +  s + ". Expected " + c.toString() + " but got " + r.toString());
        } else {
            console.info("Correct parsing for: " + s);
        }
    }
} catch (e) {
    console.error("!!!! Failed to parse: " + s + "\n" + e.stack);
}

JSFIDDLE

Remove quotes from your regex and use regex delimiters /.../ :

var obj = {
    "/without flags/": new RegExp("without flags"),
    "/something/gi": new RegExp("something", "gi"),
    "/with\/slashes\//gi": new RegExp("with\/slashes\/", "gi"),
    "/with \/some\/(.*)regex/gi": new RegExp("with \/some\/(.*)regex", "gi"),
    "/^dummy.*[a-z]$/gmi": new RegExp("^dummy.*[a-z]$", "gmi"),
    "/singlehash": new RegExp("/singlehash"),
    "single/hash": new RegExp("single/hash"),
    "raw input": new RegExp("raw input")
};
var re = /^(?:\/(.*?)\/([a-z]*)|(.+))$/i;

try {
    for (var s in obj) {
        var c = obj[s];
        var m = s.match(re);    
        if (m === null || m[1]+m[3] === undefined) {
            console.error("null result for: " + s, m);
            continue;
        }
        var regex = (m[1]==undefined)?m[3]:m[1];

        var r = (m[2]==undefined) ? new RegExp(regex) : new RegExp(regex, m[2]);
        if (r.toString() !== c.toString()) {
            console.error("Incorrect parsing for: " +  s + ". Expected " + c.toString() + " but got " + r.toString());
        } else {
            console.info("Correct parsing for: " + s);
        }
    }
} catch (e) {
    console.error("!!!! Failed to parse: " + s + "\n" + e.stack);
}

- JSFiddle Demo

- RegEx Demo

This will work even if there're \\/ inside the regex: /(\\/?)(.+)\\1([az]*)/i

With delimiters and flags:

var matches = "/some regex/gi".match(/(\/?)(.+)\1([a-z]*)/i);

output:

["/some regex/gi", "/", "some regex", "gi"]

Without delimiters:

var matches = "without flags".match(/(\/?)(.+)\1([a-z]*)/i);

output:

["without flags", "", "without flags", ""]

With all our test cases:

var matches = "/some regex/gi".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["/some regex/gi", "/", "some regex", "gi"]

var matches = "some regex".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["some regex", "", "some regex", ""]

var matches = "/with\/slashes\//gi".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["/with/slashes//gi", "/", "with/slashes/", "gi"]

var matches = "/with \/some\/(.*)regex/gi".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["/with /some/(.*)regex/gi", "/", "with /some/(.*)regex", "gi"]

var matches = "/^dummy.*[a-z]$/gmi".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["/^dummy.*[a-z]$/gmi", "/", "^dummy.*[a-z]$", "gmi"]

var matches = "/singlehash".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["/singlehash", "", "/singlehash", ""]

var matches = "single/hash".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["single/hash", "", "single/hash", ""]

var matches = "raw input".match(/(\/?)(.+)\1([a-z]*)/i);
==> ["raw input", "", "raw input", ""]

The regex is in matches[2] and flags in matches[3]

Use backtracking . See this regex:

/^(?:\/(.*)\/([a-z]*)|(.*))$/

Here is an online code demo . Works now.

Why not just

/\/(.*)\/(.*)|(.*)/

In English

Look for either
    a slash, followed by
    a (greedy) sequence of characters,
    a closing slash,
    and an optional sequence of flags
or
    any sequence of characters

See http://regex101.com/r/aY1oS8/2 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM