2

I have a long String which is dynamic. Wherever % XXX % is found, I have to get the XXX value and replace it with some other value. There will be multiple % XXX %. How can I get the value within the % %?

For Eg.

"POLICY_NO = %POLNO%  and b.ACTION_TIME = (select max(ACTION_TIME) from POLICY_DETAILS where POLICY_NO = %POLICYID%)"

How can I read each value between 2 %? And I have to take POLNO and compare it with some session variables(Eg,POLNO=1234567,POLICYID=3) and if it is matched then i have to replace the session variable value. Then the query sholud become as

"POLICY_NO = 1234567 and b.ACTION_TIME = (select max(ACTION_TIME) from POLICY_DETAILS where POLICY_NO = 3)"

Mr.Chowdary
  • 517
  • 1
  • 6
  • 18
  • So each different "property" in the string should be replaced with a different value? Are all the possible "properties" known in advance (i.e. there are 6 possible values)? – John B Apr 26 '12 at 11:15
  • Properties are possible values like POLNO, POLID.. I have to get the values from 2 % first. Next Compare with Map keys..If found then have to replace with Map Value of the specific Key... – Mr.Chowdary Apr 26 '12 at 11:57

4 Answers4

3

Look at String.format() class method method, but if it is for SQL you should consider using PreparedStatement those are standard java classes.

Here is an example of String.format

String formatted = String.format("%d is a number and %s is another string", 20, "Test");
System.out.println(formatted);
  • That is okay.. But the possible variables like POLNO, POLID.. I have to get the variable from 2 % first. Next Compare with Map keys..If found then have to replace with Map Value of the specific Key... – Mr.Chowdary Apr 26 '12 at 13:43
3

Well, you could use Pattern and Matcher to get all strings between two percent characters (%). For this, try the following expression: %([^%]*)%

You'd still have to evaluate the strings you found.

Alternatively, if you know what could occur here (or what should be supported) just use someString.replace("%POLNO%", "somevalue").

Howver, if this is for SQL, you might want to look into prepared statements (with some extensions) or some OR mapper instead. What you basically have in that case is named parameters.

Community
  • 1
  • 1
Thomas
  • 87,414
  • 12
  • 119
  • 157
3

Considering only the substitution in strings:

  • If you don't know which variables you should replace or its values, you can do is:

    // Map simulate your session variables.
    Map<String, String> variables = new HashMap<String, String>();
    variables.put("POLNO", "V1");
    variables.put("POLICYID", "V2");
    
    String input =
    /**/"POLICY_NO = %POLNO% and A.POLICY_DETAILS_ID = " +
    /**/"b.POLICY_DETAILS_ID and b.ACTION_TIME = " +
    /**/"(select max(ACTION_TIME) from POLICY_DETAILS " +
    /**/"where POLICY_NO = %POLICYID%)";
    
    StringBuilder output = new StringBuilder(input);
    
    int offset = 0;
    
    Matcher matcher = Pattern.compile("(%)([^%]*)(%)").matcher(input);
    while (matcher.find()) {
        // Get only second group (variable name), ignoring % symbols
        String variable = matcher.group(2);
        String value = variables.get(variable);
    
        // Calculate the offset.
        // The previous replaces can change the string length
        int start = matcher.start() + offset;
        int end = matcher.end() + offset;
    
        // Replace %XXX% by its value
        output.replace(start, end, value);
    
        offset -= variable.length() + 2 - value.length();
    }
    
  • Otherwise, you can chain multiply calls:

    String.replace("%XXX%", "VALUE")
    
2

I agree that you should use PreparedStatement to prevent SQL injection.

But if you decide to do replacement in String, appendReplacement works fine:

final String in = "POLICY_NO = %POLNO% and A.POLICY_DETAILS_ID = b.POLICY_DETAILS_ID and b.ACTION_TIME = (select max(ACTION_TIME) from POLICY_DETAILS where POLICY_NO = %POLICYID%)";

// initialize map
final Map<String, String> map = new HashMap<String, String>();
map.put( "POLNO", "1234567" );
map.put( "POLICYID", "3" );

final Pattern pattern = Pattern.compile( "%.*?%" );
final Matcher matcher = pattern.matcher( in );
final StringBuffer sb = new StringBuffer();
while ( matcher.find() ) {
    final String found = matcher.group();
    final String withoutPercents = found.substring( 1, found.length() - 1 );
    matcher.appendReplacement( sb, map.get( withoutPercents ) );
    // instead of map.get(), there could be session.getAttribute( withoutPercents  )
}
matcher.appendTail( sb );
System.out.println( sb.toString() );

UPD: according to comment below

Betlista
  • 10,327
  • 13
  • 69
  • 110
  • Hi Betlista, There the map contains only the session variables only..But not with %... so please enhance it to work with only POLNO, POLNOID... – Mr.Chowdary Apr 26 '12 at 13:04