J22
J22

Reputation: 223

Reformat PHP code with Perl

Imagine we have following PHP code:

if (true)
{
    doSomething();
}

But we want to have:

if (true) {
    doSomething();
}

I figure we can use the Perl in-place mass edit facility to make this sort of change across an entire codebase.

But I just cannot get it to match a newline followed by whitespace then a brace.

Here's what I'm trying

perl -pi -w -e 's/if(.*)\n\s+\{/if$1 \{/g'  testfile.php

I'm at a complete loss; it matches if I don't include the whitespace and brace. But that's not very helpful.

Upvotes: 3

Views: 193

Answers (3)

knb
knb

Reputation: 9295

Use Perl::Tidy or its commandline-tool perltidy.

I recommend you take your PHP code and reformat the source one block after a time. Copy and paste it block-wise into an empty text file, (so that you PHP fragments are still syntactically valid Perl-code), and then perl-tidy that file. If sufficient, substitute back into your PHP code file.

This way, you can use Perl::Tidy to format complex, nested, PHP data structures (better than nothing).

perltidy cannot be used to format generic PHP code (just as an example, PHP's /* */ C-style multiline comments are a problem for perltidy)

AFAIK know, there is no PHP beautifier as powerful as perltidy. I was looking for this a few years ago; so meanwhile, things might have changed.

Upvotes: 0

Egga Hartung
Egga Hartung

Reputation: 1091

If you wanted to change your Perl code base, I would strongly recommend to use Perl::Tidy. But I assume, there is a similar tool for PHP.

You would go through the possible options once and define your preferred style. Save it in a config file and reformat your whole code base. You could even add this step as a commit hook to your versioning system to have a consistent appearance.

That has two big advantages over any regular expressions:

  1. You save time, because you define all your style preferences in one run. Let's say that takes two hours. I don't see you writing regular expressions covering the same amount of options in the same time.
  2. And even more important (although you may say, that this never happens, but it most certainly will): Sooner or later you're gonna have some exceptional code, which isn't covered by your regex. Could be an if that is not detected or another construct, which matches the regex, but shouldn't be replaced. In the best case, your reformater crashes and you have to adjust your regex. In the worst case, the reformater introduces bugs in your code and you don't even notice that - until the code runs.

Upvotes: 1

Qtax
Qtax

Reputation: 33908

Using -p makes Perl loop over the lines of the file, one line at a time, thus preventing you to match content over several lines.

You can use -0 to set the input record separator to null and make Perl read the whole file at once. (See perlrun.)

You can try something like this:

perl -p0iwe 's/\bif\b(.*)\n\s*\{/if$1 \{/g' test.php

Note that this isn't a great solution for editing PHP. Strings, comments and the text content of the file are just a few things that would easily break such a simplistic solution. I suggest finding a right tool for the job. Some editors/IDEs have support for (re)formatting your code, maybe you can try one of those.

Upvotes: 3

Related Questions