klorenz / atom-regex-railroad-diagrams

display regex as railroad diagram, if cursor moves to it
MIT License
250 stars 31 forks source link

PHP regex delimiters throw errors #16

Closed valorin closed 9 years ago

valorin commented 10 years ago

PHP uses delimiters around a regex string, see: http://php.net/manual/en/regexp.reference.delimiters.php . However, this confuses this plugin completely. For example, this is a valid regex in PHP:

preg_match("/^abc[def]g/",$target)

But it throws this error:

"/^abc[def]g/"
 ^
 Expected "$", "(", ".", "\\", "\\0", "\\A", "\\B", "\\D", "\\G", "\\S", "\\W", "\\Z", "\\b", "\\c", "\\d", "\\f", "\\n", "\\r", "\\s", "\\t", "\\u", "\\v", "\\w", "\\x", "\\z", "|", CharacterSet, Literal or Quantifier but "/" found.

Is there any way to check for .php files and handle the delimiter automatically?

seb2411 commented 10 years ago

Same for me.

SharpenedSpoon commented 10 years ago

This is a very hacky solution, but I just wanted this to work for a little while and I figured I'd take it down if/when it causes issues that I don't already forsee.

Looks like the issue is that the regex parser is expecting a "clean" regex expression to parse, but when you give it a PHP string it sees the quotes and forward slashes before it sees the 'inside' of the regex, and it immediately throws an error.

I went into regex-railroad-diagram/lib/regex-to-railroad.coffee in version 0.6.2 around line 200, inside the parseRegex function. I added three "if" statements that simply try to peel away any quotes and/or forward slashes before the string is sent to the parser.

Here is my parseRegex function now:

parseRegex = (regex) ->
    if regex instanceof RegExp
        regex = regex.source

    if regex.charAt(0) == "'" && regex.charAt(regex.length - 1) == "'"
            regex = regex.substr(1, regex.length - 2)
    if regex.charAt(0) == "\"" && regex.charAt(regex.length - 1) == "\""
            regex = regex.substr(1, regex.length - 2)
    if regex.charAt(0) == "/" && regex.charAt(regex.length - 1) == "/"
            regex = regex.substr(1, regex.length - 2)

    parse regex

So far it hasn't broken anything, and allows me to use this with PHP regex!

valorin commented 10 years ago

@SharpenedSpoon Ignoring the obvious hard-coded character issues, that solution wouldn't handle a regex string with a pattern modifier on the end.

For example, if we add an i for case insensitive matching: "/^abc[def]g/i"

That said, I can't think of a nice solution myself...

One possibe solution is to use a regex to identify delimiters by a character that exists first and last in the string, white listing the allowed pattern modifiers after the last delimiter, and maybe check for a .php extension so this complex matching only happens on these files.

SharpenedSpoon commented 10 years ago

@valorin Oh yeah, it's terribly, terribly hack-y. Is there support in this plugin for pattern modifiers at all? If not, then perhaps we might just trim the fat on either end - just find the forward slashes and get everything inside?

....my vocab is lacking, sorry. It's been a long day :)

klorenz commented 9 years ago

this is fixed.