使用regexp java string查找和替换字符

时间:2015-07-28 18:31:37

标签: java regex string replace

我想在以下字符串之间替换特殊字符,只要它们位于两个单词BEGIN和END之间。 xxx到CCC和yyy到DDD,使用Java正则表达式还是某种方式?你可以帮忙吗?


Raw string = "John Doe xxx Amazing man BEGIN reference xxx yes yyy indeed this is true xxx 
no yyy END , so this xxx does not change" 


converted String = "John Doe xxx Amazing man BEGIN reference CCC yes DDD indeed this is true 
CCC no DDD END, so this xxx does not change" 

2 个答案:

答案 0 :(得分:1)

Even though your sample data displays <html> <head> <title>Order Is Processing</title> </head> <body> <?php $name = $_POST['name']; $address = $_POST['address']; $phone = $_POST['phone']; $mobile = $_POST['mobile']; $email = $_POST['email']; $date = $_POST['date']; $star = $_POST['star']; $log = $_POST['log']; $round = $_POST['round']; $totalcakes = $_POST['totalcakes']; $totalprice = $_POST['totalprice']; $formcontent="From: $name \n Address: $address \n Phone: $phone \n Mobile: $mobile \n Email: $email \n Date: $date \n Star: $star \n Log: $log \n Round: $round \n Total Cakes: $totalcakes \n Total Price $totalprice"; $recipient = "demondestiny@hotmail.com"; $subject = "New Order From Christmas Cakes For Cancer Research"; $mailheader = "From: $email \r\n"; mail($recipient, $subject, $formcontent, $mailheader) or die("Error!"); echo("Your order has been sent. Please <a href='http://www.christmascakesforcancerresearch.com.au/order_form.html'>click here</a> to go back and send through the money as a Direct Bank Deposit otherwise <form action='https://www.paypal.com/cgi-bin/webscr' method="'post' target='_top'>"); echo("<input type='hidden' name='cmd' value='_xclick'>"); echo("<input type='hidden' name='business' value='test@test.com'>"); echo("<input type='hidden' name='lc' value='AUD'>"); echo("<input type='hidden' name='item_name' value='Christmas Cakes'>"); echo("<input type='hidden' name='button_subtype' value='services'>"); echo("<input type='hidden' name='no_note' value='0'>"); echo("<input type='hidden' name='currency_code' value='AUD'>"); echo("<input type='hidden' name='bn' value='PP-BuyNowBF:btn_buynowCC_LG.gif:NonHostedGuest'>"); echo("<table>"); echo("<tr><td><input type='hidden' name='on0' value='Cakes'>Cakes</td></tr><tr><td><select name='os0'>"); echo("<option value='Star'>Star $15.00 AUD</option>"); echo("<option value='Log'>Log $25.00 AUD</option>"); echo("<option value='Round'>Round $60.00 AUD</option>"); echo("</select> </td></tr>"); echo("</table>"); echo("<input type='hidden' name='currency_code' value='AUD'>"); echo("<input type='hidden' name='option_select0' value='Star'>"); echo("<input type='hidden' name='option_amount0' value='15.00'>"); echo("<input type='hidden' name='option_select1' value='Log'>"); echo("<input type='hidden' name='option_amount1' value='25.00'>"); echo("<input type='hidden' name='option_select2' value='Round'>"); echo("<input type='hidden' name='option_amount2' value='60.00'>"); echo("<input type='hidden' name='option_index' value='0'>"); echo("<input type='image' src='https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif' border='0' name='submit' alt='PayPal - The safer, easier way to pay online!'>"); echo("<img alt='' border='0' src='https://www.paypalobjects.com/en_US/i/scr/pixel.gif' width='1' height='1'> </form>"); ?> </body> </html> before "xxx", there's no specification if "yyy" is before "xxx" or vice versa. You just state, "yyy".

I see having a "special characters between the following String when only when they are between two words, BEGIN and END" where the keys are your "special" strings and the values are the strings that'll replace the "special" strings.

Iterate through this map and provide the keys to this:

Map<String, String>

In this example, it'll produce two regex patterns:

String.format("BEGIN.*?(%s).*?END", kvp.getKey())

This will capture your "special" strings into capture group 1, which you'll provide to "BEGIN.*?(xxx).*?END" "BEGIN.*?(yyy).*?END" like so:

String.replace()

raw = raw.replace(matcher.group(), matcher.group().replace(matcher.group(1), kvp.getValue())); is the entire matching string matcher.group() and BEGIN ... END will either be matcher.group(1) or xxx

Put this all together and you have:

yyy

Results:

public static void main(String[] args) throws Exception {
    Map<String, String> replacerMap = new HashMap() {{
        put("xxx", "CCC");
        put("yyy", "DDD");
    }};

    String raw = "John Doe xxx Amazing man BEGIN reference xxx yes yyy indeed this is true xxx no yyy END , so this xxx does not change";
    System.out.println("Before: ");
    System.out.println(raw);
    System.out.println();

    for (Map.Entry<String, String> kvp : replacerMap.entrySet()) {
        Matcher matcher = Pattern.compile(String.format("BEGIN.*?(%s).*?END", kvp.getKey())).matcher(raw);
        if (matcher.find()) {
            raw = raw.replace(matcher.group(), matcher.group().replace(matcher.group(1), kvp.getValue()));
        }
    }

    System.out.println("After: ");
    System.out.println(raw);
}

答案 1 :(得分:0)

You need to define your pattern and matcher:

Pattern MY_PATTERN = Pattern.compile("BEGIN" + "([ ]*+[0-9A-Za-z]++[ ]*+)*" + "xxx" + "([ ]*+[0-9A-Za-z]++[ ]*+)*" + "END");
Matcher m = MY_PATTERN.matcher(rawString);

Then you will call the find method on the matcher and every time it finds what you wanted will replace it with what you needed:

 while (m.find()) {
        rawString = rawString.replaceFirst(m.group(0),m.group(0).replaceAll("xxx","CCC"));
    }
相关问题