MightyOak
MightyOak

Reputation: 23

Java regex not replacing properly

Below is a code snippet where I want to replace few strings. I am using date_add pattern two places in my code, but its getting replaced only once.I am using string.replaceAll but still its not working for me. Please help me identifying the reason.

public class Implementation {

 public static void main(String[] args) {
   String ipquery = "select  to_date(id)  from location_dim location_dim where ( location_name  =  '123' ) limit 10 union all select  item_id  " +
        "item_id  from  (select item_dim.time_id from item_dim item_dim where item_dim.time_id in  (  select time_dim.id from time_dim " +
        "where (( time_dim . day ) = date_add( '1999-01-01' ,  2 )) ) ) item_dim inner join time_dim  time_dim  on (( item_dim . time_id ) " +
        "= ( time_dim . id )) where (( time_dim . day ) = date_add( '1999-01-01' ,  2 )) limit 20";
   System.out.println(replace(ipquery));

 }

public static String replace(String query) {
  Map<String, String> imputnmatch = new HashMap<String, String>();
  imputnmatch.put("to_date", "date");
  imputnmatch.put("format_number", "format");
  imputnmatch.put("date_sub\\((.*),\\s*([0-9]+\\s*)\\)",
      "date_sub($1, interval $2 day)");
  imputnmatch.put("date_add\\((.*),\\s*([0-9]+\\s*)\\)",
      "date_add($1, interval $2 day)");
  for (Map.Entry<String, String> entry : imputnmatch.entrySet()) {
    query = query.replaceAll(entry.getKey(), entry.getValue());
    System.out.println(entry.getKey() + "  " + entry.getValue() + "   " +query);
  }
  return query;
}

}

Upvotes: 0

Views: 57

Answers (2)

Munir
Munir

Reputation: 51

you are using .* that also include ")" so your one date_sub is include in date_sub pattern. so change your date_sub & date_add pattern It will help you

Upvotes: 1

Pshemo
Pshemo

Reputation: 124225

In "date_add\\((.*),\\s*([0-9]+\\s*)\\)" pattern .* will try to find maximal potential match, so it will try to find part which will start with date_add\\( and will end with ,\\s*([0-9]+\\s*)\\) which means that in data

select to_date(id) from location_dim location_dim where ( location_name = '123' ) limit 10 union all select item_id item_id from (select item_dim.time_id from item_dim item_dim where item_dim.time_id in ( select time_dim.id from time_dim where (( time_dim . day ) = date_add( '1999-01-01' , 2 )) ) ) item_dim inner join time_dim time_dim on (( item_dim . time_id ) = ( time_dim . id )) where (( time_dim . day ) = date_add( '1999-01-01' , 2 )) limit 20

it will match

select to_date(id) from location_dim location_dim where ( location_name = '123' ) limit 10 union all select item_id item_id from (select item_dim.time_id from item_dim item_dim where item_dim.time_id in ( select time_dim.id from time_dim where (( time_dim . day ) = date_add( '1999-01-01' , 2 )) ) ) item_dim inner join time_dim time_dim on (( item_dim . time_id ) = ( time_dim . id )) where (( time_dim . day ) = date_add( '1999-01-01' , 2 )) limit 20

To make .* search for minimal match you need to make * quantifier reluctant (lazy) by adding ? after it. So try with

"date_add\\((.*?),\\s*([0-9]+\\s*)\\)"
//             ^-add this

Same rule apples for date_sub\\((.*),\\s*([0-9]+\\s*)\\) pattern, which means you need should change it to date_sub\\((.*?),\\s*([0-9]+\\s*)\\)

Upvotes: 2

Related Questions