13

I am trying to replace public methods to protected methods for methods that have a comment.

This because I am using phpunit to test some of those methods, but they really don't need to be public, so I'd like to switch them on the production server and switch back when testing.

Here is the method declaration:

public function extractFile($fileName){ //TODO: change to protected

This is the regexp:

(?<ws>^\s+)(?<pb>public)(?<fn>[^/\n]+)(?<cm>//TODO: change to protected)

If I replace it with:

\1protected\3\//TODO: change back to public for testing

It seems to be working, but what I cannot get to work is naming the replace with. I have to use \1 to get the first group. Why name the groups if you can't access them in the replacing texts? I tried things like <ws>, $ws, $ws, but that doesn't work.

What is the replacing text if I want to replace \1 with the <ws> named group?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
HMR
  • 37,593
  • 24
  • 91
  • 160
  • Thank you, that didn't do it though. Can't find it anywhere in the documentation. If you can name groups you'd think you can use it in the replacement string. I usually up vote any answer that's useful, now I see you can accept it as well. Will do this now. – HMR Nov 29 '12 at 01:10

1 Answers1

11

The ?<ws> named group syntax is the same as that used by .NET/Perl. For those regex engines the replacement string reference for the named group is ${ws}. This means your replacement string would be:

${ws}protected${fn}\//TODO: change back to public for testing

The \k<ws> reference mentioned by m.buettner is only used for backreferences in the actual regex.

Extra Information:

It seems like Geany also allows use of Python style named groups:

  • ?P<ws> is the capturing syntax
  • \g<ws> is the replacement string syntax
  • (?P=ws) is the regex backreference syntax

EDIT:

It looks my hope for a solution didn't pan out. From the manual,

A subpattern can be named in one of three ways: (?...) or (?'name'...) as in Perl, or (?P...) as in Python. References to capturing parentheses from other parts of the pattern, such as backreferences, recursion, and conditions, can be made by name as well as by number.

And further down:

Back references to named subpatterns use the Perl syntax \k or \k'name' or the Python syntax (?P=name).

and

A subpattern that is referenced by name may appear in the pattern before or after the reference.

So, my inference of the syntax for using named groups was correct. Unfortunately, they can only be used in the matching pattern. That answers your question "Why name groups...?".

How stupid is this? If you go to all the trouble to implement named groups and their usage in the matching pattern, why not also implement usage in the replacement string?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
robinCTS
  • 5,746
  • 14
  • 30
  • 37
  • Thank you for your answer. Maybe I have a different geany but if I have the text "win7" using expression "(?win)7" replacing with: "${w}8" the result is: "${w}8" using geany 1.22 – HMR Jan 22 '13 at 01:49
  • @HMR - I don't actually have geany. I made the observation that the capturing syntax was the same as for .NET/Perl, which was confirmed when I checked the online manual as both allow `?'ws'` also. I hoped that the underlying regex engine would allow the same style named captures in the replacement string. Just did some more reading of the manual. Seems like named groups are _not_ allowed in the replacement string. I'll edit my answer to include more details. – robinCTS Jan 22 '13 at 05:16
  • Thank you robin for taking the time to look into this one. I didn't find anything in the documentation about the replacement string but want to make sure sure I didn't overlook something before ruling it out. – HMR Jan 22 '13 at 05:25
  • @HMR - You're welcome. Sorry I couldn't be the bringer of good news. If you feel like awarding me the bounty, don't forget to either accept my answer, or manually award it :-) – robinCTS Jan 22 '13 at 06:10
  • I thought the same thing, it's silly to have named groups but then you can't use them in the replace. I like working with geany when on Linux and can refer to the group by number in the replace string but it just bugged me. Thank you for the time you've put in. Before asking this question I had spend quite some time on it as well. – HMR Jan 22 '13 at 07:30
  • 2
    @HMR I know this is an old question, but I got it working on Geany using `(?<1>PATTERN)` as the search string and `\1` as the replace string. Maybe you should use \ws... – Alex Jun 12 '13 at 03:16
  • 2
    @Alex - You seem to have missed the whole point of the question. We _know_ `(?<1>PATTERN)`->`\1` works. So would `(?<2>PATTERN)`->`\1` and `(?PATTERN)`->`\1`. But `(?<2>PATTERN)`->`\2` wouldn't. Nor would `(?PATTERN)`->`\ws`. (Since you have Geany, you probably should have actually tried `(?PATTERN)`->`\ws` _before_ posting the suggestion ;-) ). `(?<` **anything** `>PATTERN)`, where **anything** is a string, means a _named_ capturing group with name **anything** (eg, "1"). `\n`, where **n** is a number, means the nth capturing group. `\ws` means literally "\ws". – robinCTS Jun 12 '13 at 20:49
  • Request for named group is an open issue: https://github.com/geany/geany/issues/1519 – Cas Mar 05 '20 at 13:38
  • It is not clear what *"The \k reference mentioned by m.buettner"* refers to. It was included in the first revision of this answer (thus before any comments to this answer). – Peter Mortensen Nov 01 '20 at 04:33