/*bin/mkdir /tmp/rip 2> /dev/null
javac -d /tmp/rip $0
java -cp /tmp/rip Rip "$@"
exit
*/
import java.io.*;
import java.util.*;
import java.util.regex.*;

public class Rip {

  private final boolean skipUnmatched;
  private final String newline;
  private final String format;
  private final Pattern pattern;

  public Rip(boolean skipUnmatched, String newline, String format, Pattern pattern) {
    this.skipUnmatched = skipUnmatched;
    this.newline = newline;
    this.format = format;
    this.pattern = pattern;
  }

  private boolean rip() throws IOException {
    boolean success = true;
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String line;
    while((line = in.readLine()) != null) {
      Matcher matcher = pattern.matcher(line);
      if (!matcher.find()) {
        if (!skipUnmatched) {
          System.err.println("Rip: Couldn't match \"" + line + "\"");
          success = false;
        }
        continue;
      }

      Object[] groups = new Object[matcher.groupCount() + 1];
      for (int g = 0; g < groups.length; g++) {
        groups[g] = matcher.group(g);
      }

      try {
        System.out.print(String.format(format, groups));
        System.out.print(newline);
      } catch (IllegalFormatException e) {
        System.err.println("Rip: Couldn't format " + Arrays.asList(groups) + ", " + e.getMessage());
        success = false;
      }
    }
    return success;
  }

  public static void main(String[] args) throws IOException {
    boolean skipUnmatched = false;
    String newline = String.format("%n");

    List<String> argsList = new ArrayList<String>(Arrays.asList(args));
    for (Iterator<String> a = argsList.iterator(); a.hasNext(); ) {
      String arg = a.next();
      if ("-s".equals(arg) || "--skip_unmatched".equals(arg)) {
        skipUnmatched = true;
        a.remove();
      }

      if ("-n".equals(arg) || "--newline".equals(arg)) {
        a.remove();
        newline = a.next();
        a.remove();
      }
    }

    if (argsList.size() != 2) {
      printUsage();
      System.exit(1);
    }

    String regex = argsList.get(0);
    String format = argsList.get(1);
    Pattern pattern = Pattern.compile(regex);

    Rip rip = new Rip(skipUnmatched, newline, format, pattern);
    boolean success = rip.rip();

    if (!success) {
      System.err.println("Rip: Failed. Regex=\"" + regex + "\", Format=\"" + regex + "\"");
      System.exit(-1);
    }
  }

  public static void printUsage() {
    System.out.println("Usage: Rip [flags] <regex> <format>");
    System.out.println();
    System.out.println("  regex: a Java regular expression, with groups");
    System.out.println("  http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html");
    System.out.println("         you can (parenthesize) groups");
    System.out.println("         \\s whitespace");
    System.out.println("         \\S non-whitespace");
    System.out.println("         \\w word characters");
    System.out.println("         \\W non-word");
    System.out.println();
    System.out.println("  format: a Java Formatter string");
    System.out.println("  http://java.sun.com/javase/6/docs/api/java/util/Formatter.html");
    System.out.println("          %[argument_index$][flags][width][.precision]conversion");
    System.out.println("          '%s', '%1$s' - the full matched text");
    System.out.println("          '%2$s' the first (parenthesized) group");
    System.out.println();
    System.out.println("  Use 'single quotes' to prevent bash from interfering");
    System.out.println();
    System.out.println("flags:");
    System.out.println("  --skip_unmatched: ignore input that doesn't match <regex>");
    System.out.println("                -s:");
    System.out.println();
    System.out.println("  --newline <text>: use <text> to separate lines in output");
    System.out.println("         -n <text>:");
    System.out.println();
  }
}
