Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reformatting code with Regular Expressions

We have an ArrayList of items in several classes which are giving me trouble every time I'd like to insert a new item into the list. It was a mistake on my part to have designed the classes in the way I did but changing the design now would be more headache than it's worth (bureaucratic waterfall model.) I should have anticipated format changes to the documents the customer was supplying us waterfall be damned.

I'd like to write a simple script in python which goes into a class, adds the item to the list, and then increments all retrievals for the following items. That doesn't sound very explanatory:

Foo extends Bar{
    public Foo(){
        m_Tags.add("Jane");
        m_Tags.add("Bob");
        m_Tags.add("Jim");
    }

    public String GetJane() { return m_ParsedValue.get( m_Tags.get(1) ); }
    public String GetBob() { return m_ParsedValue.get( m_Tags.get(2) ); }
    public String GetJim() { return m_ParsedValue.get( m_Tags.get(3) ); }
}

You see if I want to add a value between "Jane" and "Bob" I then have to increment the integers in the Get* functions. I just want to write a simple script in Python that does the work for me. Someone I very much respect suggested regex.

Edit:

Yes, LinkedHashMap. So simple, so easy and so not in the design specs now. I hate waterfall. Hate it with a passion. This whole bit was a "small" and "easy" part that "shouldn't take much time to design." I made mistakes. It's stuck in stone now.

like image 628
wheaties Avatar asked Jan 26 '10 15:01

wheaties


1 Answers

You want your regular expression to be as flexible as the compiler will be with respect to whitespace between tokens. Doing so and mimicking whitespace usage makes the pattern pretty messy. The code below (sorry: Perl, not Python) edits your source files in-place.

#! /usr/bin/perl -i.bak    
use warnings;
use strict;
my $template =
  '^( public
      String
      Get)(\w+)( \( \) { return
        m_ParsedValue . get \( m_Tags . get \( )(\d+)( \) \) ; } )$';
$template =~ s/ +/\\s*/g;
$template =~ s/(\r?\n)+/\\s+/g;
my $getter = qr/$template/x;

die "Usage: $0 after new-name source ..\n" unless @ARGV >= 3;
my $after = shift;
my $add   = shift;
my $index;
while (<>) {
  unless (/$getter/) {
    print;
    next;
  }
  my($abc,$name,$lmno,$i,$xyz) = ($1,$2,$3,$4,$5);
  if (defined $index) {
    print join "" => $abc, $name, $lmno, ++$index, $xyz;
  }
  else {
    if ($name eq $after) {
      $index = $i;
      print; print join "" => $abc, $add, $lmno, ++$index, $xyz;
    }
    else { print; }
  }
}

For example,

$ ./add-after Jane Foo code.java
$ cat code.java
Foo extends Bar{
    public Foo(){
        m_Tags.add("Jane");
        m_Tags.add("Bob");
        m_Tags.add("Jim");
    }

    public String GetJane() { return m_ParsedValue.get( m_Tags.get(1) ); }
    public String GetFoo() { return m_ParsedValue.get( m_Tags.get(2) ); }
    public String GetBob() { return m_ParsedValue.get( m_Tags.get(3) ); }
    public String GetJim() { return m_ParsedValue.get( m_Tags.get(4) ); }
}
like image 105
Greg Bacon Avatar answered Oct 17 '22 12:10

Greg Bacon