2

The Issue

The issue I am tackling is that past developers of some code I am working on set variables like $_GET[name] or sometimes like $_GET['name']. Trying to make the code uniform, I want to make all of them like $_GET['name']

Attempted Solution

In a custom DreamWeaver script, I have used the following.

dreamweaver.setUpFindReplace({
    searchString: "\$(_POST|_SESSION|_GET)\[([^\'][0-9a-zA-Z _]+?[^\'])\]",
    replaceString: "$$1['$2']",
    searchWhat: "document",
    searchSource: true,
    useRegularExpressions: true
});
dreamweaver.replaceAll();

Extra Information

While I am getting the error running it from a custom script, I do not get it when running the same "searchString" and "replaceString" within the Find Prompt (CTRL + F).

The find prompt will happily find, and replace the instances where it occurs.

Before someone potentially points out the fact - yes, I could just run the Find Prompt and do it from there, but I still have to run the custom script to run the other 20 or so find and replace options.

Do you have example end results somewhere?

Sure do. I have the regex used on Regex 101 - https://regex101.com/r/bE9kN6/1

Finally...

Anybody know how to stop the unmatched parenthesis issue? Been trying for a while now and I can't find a resolution since there are no unmatched parenthesis.

Solution

Thanks to Bob for figuring this out. Dreamweaver uses JS regex (which I did not believe was different to PHP, but turns out one is POSIX and one is perl-regex [or something...]) and that literals need escaping with \\ not \.

This made the final, working, function;

dreamweaver.setUpFindReplace({
    searchString: "\\$(_POST|_SESSION|_GET)\\[([^\'][0-9a-zA-Z _]+?[^\'])\\]",
    replaceString: "$$1['$2']",
    searchWhat: "document",
    searchSource: true,
    useRegularExpressions: true
});
dreamweaver.replaceAll();
  • I can't see any error (nor can Regex101), and I am led to the conclusion that you have found a bug in DreamWeaver. I don't think the single quote would have any special meaning in the searchString parameter, so you could try it without the preceding back-slash and see if that works round it. If not, try simplifying the second marked expression until you lose the error: it won't do what you want, but that doesn't matter for now. – AFH Apr 2 '16 at 14:40
  • Thanks for the reply AFH. Just got to work and in front of a computer, so shall try that now - I'll post back here shortly. – MrMarlow Apr 4 '16 at 7:35
  • That would be a negative - stripping all the way back to \$(_POST|_SESSION|_GET)\[ gives "Unterminated character class" but works on regex101 - and making the search greedy using \$(_POST|_SESSION|_GET)\[(.+?)\] doesn't replace with the ReplaceWith parameter. Starting to dislike DW Regex. – MrMarlow Apr 4 '16 at 7:44
  • Further testing - even searchString: "\$(_POST|_SESSION|_GET)", replaceString: "\$_GET", does not replace $_POST and $_SESSION with $_GET. – MrMarlow Apr 4 '16 at 7:46
  • @SlackBadger Have you tried escaping the backslashes? I've not used DreamWeaver, but that looks a lot like JS and in a JS string literal "\[" becomes [ where you probably want "\\[" to become \[. Try using double backslashes in the string literal everywhere you want a backslash in the actual regex. – Bob Apr 4 '16 at 7:57
1
+100

Your escaping is a bit off. You seem to be using JavaScript, and the string literal "\$(_POST|_SESSION|_GET)\[([^\'][0-9a-zA-Z _]+?[^\'])\]" evaluates to $(_POST|_SESSION|_GET)[([^'][0-9a-zA-Z _]+?[^'])].

Instead, you should use "\\$(_POST|_SESSION|_GET)\\[([^'][0-9a-zA-Z _]+?[^'])\\]", which evaluates to \$(_POST|_SESSION|_GET)\[([^'][0-9a-zA-Z _]+?[^'])\].


The reason here is because you actually have two levels of parsing going on, each with its own escaping rules. First, you have the JavaScript string literal, which allows escaping things like \n for a new line. However, unrecognised escape sequences like "\[" are silently swallowed and produce [. The regex engine sees [, indicating the start of a character class.

You want the regex engine to receive literal backslashes in the pattern. To do so, you must first produce a JS string containing literal backslashes. Which means you must escape the backslashes themselves in the string literal, so "\\" produces \, e.g. "\\[" produces the string \[. This way the regex engine sees \[, indicating an escaped (literal) bracket.

The other thing is that the single quotes do not need to be escaped at all, since they hold no special meaning in regex and single quotes inside a double-quoted string are treated as normal characters by JS.


There is another option, but I'm not sure if DreamWeaver accepts it. JavaScript has a special regex literal syntax, so you don't have to create a string first. By skipping that extra parsing step, you actually avoid the need to double-escape. A JS regex literal is of the form /pattern/options (forward-slashes need to be escaped, but you don't have any in this pattern). So your pattern can be expressed as /\$(_POST|_SESSION|_GET)\[([^'][0-9a-zA-Z _]+?[^'])\]/. Once again, the single quotes do not need to be escaped at all.

If DreamWeaver supports the regex literal syntax, this is actually the preferred option.

  • You may award your bounty in 21 hours - I'll give this in the morning :) – MrMarlow Apr 4 '16 at 10:46
  • Well spotted - I completely missed that. – AFH Apr 4 '16 at 13:10
  • Now selected as best answer - I would also vote you up, but apparently I need 15 reputation for that and giving 100 away means I am now at 13 - bad times! – MrMarlow Apr 5 '16 at 10:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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