Kumar
Kumar

Reputation: 961

replacing the carriage return with white space in java

I am having the below string in a string variable in java.

rule "6"
no-loop true
    when
    then
    String prefix = null;
    prefix = "900";
    String style = null;
    style = "490";
    String  grade = null;
    grade = "GL";
    double basePrice = 0.0;
    basePrice = 837.00;
    String ruleName = null;
    ruleName = "SIVM_BASE_PRICE_006
Rahul Kumar Singh";
    ProductConfigurationCreator.createFact(drools, prefix, style,grade,baseprice,rulename);
end
rule "5"
no-loop true
    when
    then
    String prefix = null;
    prefix = "800";
    String style = null;
    style = "481";
    String  grade = null;
    grade = "FL";
    double basePrice = 0.0;
    basePrice = 882.00;
    String ruleName = null;
    ruleName = "SIVM_BASE_PRICE_005";
    ProductConfigurationCreator.createFact(drools, prefix, style,grade,baseprice,rulename);
end

I need to replace this the carriage return between "THEN" and "END" keyword with white space so that it becomes like below code:

rule "6"
no-loop true
    when
    then
    String prefix = null;
    prefix = "900";
    String style = null;
    style = "490";
    String  grade = null;
    grade = "GL";
    double basePrice = 0.0;
    basePrice = 837.00;
    String ruleName = null;
    ruleName = "SIVM_BASE_PRICE_006 Rahul Kumar Singh";
    ProductConfigurationCreator.createFact(drools, prefix, style,grade,baseprice,rulename);
end

rule "5"
no-loop true
    when
    then
    String prefix = null;
    prefix = "800";
    String style = null;
    style = "481";
    String  grade = null;
    grade = "FL";
    double basePrice = 0.0;
    basePrice = 882.00;
    String ruleName = null;
    ruleName = "SIVM_BASE_PRICE_005";
    ProductConfigurationCreator.createFact(drools, prefix, style,grade,baseprice,rulename);
end

In the above two example of string set, the second is correct format that I need. However, in the first set, I am getting this :

ruleName = "SIVM_BASE_PRICE_006
Rahul Kumar Singh";

This perticulerly needs to be like this:

ruleName = "SIVM_BASE_PRICE_006 Rahul Kumar Singh";

and I also need to ensure that this doesn't effect any thing else in the string. Thus I need to replace this "carriage return" with a white space and make in one line. This is my requirment. I tried with replace and replaceAll method of string but not works properly.

Problem:

I need to look in between string "then" and "end" and in that whenever there is any carriage return in between two double quaotes "" ""; I need to replace this carriage return with white space and make it in one line.

Thanks

EDIT:

DRT:

template header
Prefix
Style
Product

package com.xx
import com.xx.drools.ProductConfigurationCreator;

template "ProductSetUp"
rule "Product_@{row.rowNumber}"
no-loop true
    when
    then
      String prefix = null;
      prefix = "@{Prefix}";
      String style = null;
      prefix = "@{Style}";
      String product = null;
      product = "@{Product}";
      ProductConfigurationCreator.createProductFact(drools,prefix,style,product);
end
end template

The excel and drt are for only demostration purpose. In the Image, in Product column, there is "SOFAS \rkumar shorav". Actually this is creating problem. This will generate like below:

product = "SOFAS
kumar shorav";

I need this like below:

product = "SOFAS kumar shorav";

Then Excel data :

attached image.enter image description here

Upvotes: 2

Views: 1698

Answers (4)

laune
laune

Reputation: 31290

You might say that there is a bug in org.drools.template.parser.StringCell, method

public void addValue(Map<String, Object> vars) {
    vars.put(column.getName(), value);
}

Here, the value is added to the Map as a String but this does not take into account that string values are usually expanded into string literals. Therefore, an embedded newline should be converted to the escape sequence \n. You might try this patch:

public void addValue(Map<String, Object> vars) {
    String h = value.replaceAll( "\n", "\\\\n" );
    vars.put(column.getName(), h);
}

Take the source file, put it into a suitable subdirectory, compile it to a class file and make sure that the root directory precedes drools-templates-6.2.0.Final-sources.jar in the class path. You should then see

ruleName = "SIVM_BASE_PRICE_006\nRahul Kumar Singh";

in the generated DRL file. Obviously, this is not a space, but it is what is written in the spreadsheet cell!

I suggest (urgently) that you do not follow this approach. The reason is simply this that strings are not always expanded between quotes, and then the replacement would result almost certainly in invalid code. There is simply no remedy as the template compiler is "dumb" and does not really "know" what it is expanding.

If a String in a spreadsheet contains a line break, template expansion must render this faithfully, and break the line just there. If this produces invalid (Java) code: why was the line break entered in the first place? There is absolutely no reason not to have a space in that cell if that's what you want.

Upvotes: 1

Pshemo
Pshemo

Reputation: 124225

Instead of regex I would probably write my own formatter which will

  • check if cursor is inside quote
  • replace each \r with space
  • replace each \n with space, unless it was placed right after \r which means that space was already placed for that \r
  • write rest of characters without change.

Only possible problem is that this formatter will not care about where string is placed so if you want to format some specific part of the string you will need to provide only that part.

Code implementing such formatter can look like:

public static String format(String text){

    StringBuilder sb = new StringBuilder();
    boolean insideQuote = false;
    char previous = '\0';//to track `\r\n`

    for (char ch : text.toCharArray()) {

        if (insideQuote && 
                 (ch == '\r' || 
                  ch == '\n' && previous != '\r') ) {
            sb.append(" ");//replace `\r` or `\n` with space
        }else {
            if (ch == '"') {
                insideQuote = !insideQuote;
            }
            sb.append(ch); //write other characters without change
        }
        previous = ch;
    }

    return sb.toString();

}

helper utility method

public static String format(File file, String encoding) throws IOException {
    String text = new String(Files.readAllBytes(file.toPath()), encoding);
    return format(text);
}

Usage:

String formatted = format(new File("input.txt"), "utf-8");
System.out.println(formatted);

Upvotes: 2

Joop Eggen
Joop Eggen

Reputation: 109547

s = s.replaceAll("(?m)^([^\"]*(\"[^\"]*\")*[^\"]*\"[^\"]*)\r?\n\\s*", "$1 ");

This replaces lines with an unpaired quotes to one with the line ending replaced.

^.... means starting at the line begin
[^\"] means not quote
\r?\n catches both CR+LF (Windows) as LF (Rest) line endings

not-quotes,
    repetition of " not-quotes ",
    not quotes, quote, not-quotes, newline

Mind this does not cover backslash+quote, escapes them-selves.

Upvotes: 0

Bohemian
Bohemian

Reputation: 425003

Use the "multi line" flag:

str = str.replaceAll("(?m)^\\s+", "");

The multi-line flag (?m) makes ^ and $ match start/end of each line (rather than start/end of input). \s+ means "one or more whitespace characters".

Upvotes: -1

Related Questions