正则表达式替换添加不需要的额外支架

时间:2014-06-12 01:39:44

标签: java regex

好的,所以这是我的代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class View {

    private String item;
    private static final Pattern p = Pattern.compile("\\{(.*?)\\}");
    Matcher m;
    Map map;

    public View(String str){
        this.item = str;
        m = p.matcher(item);
        map = new HashMap();

        while(m.find()){
            String key = m.group(1);
            map.put(key, null);
        }
    }

    public void add(String str, Object obj){
        for(Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator(); it.hasNext();){
            Map.Entry<String, Object> e = it.next();
            String key = e.getKey();
            Object value = e.getValue();

            if(str.equals(key)){
                e.setValue(obj);
            }
        }
    }

    public Object render(){
        for(Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator(); it.hasNext();){
            Map.Entry<String, Object> e = it.next();
            String key = e.getKey();
            Object value = e.getValue();

            System.out.println(key + "" + value);

         item = item.replaceAll("\\{" + key + "\\}", value.toString());

        }
        return item;
    }
}

我需要它通过这两个测试:

@Test
    public void testList() {
        View view = new View("<table>{rows}</table>");
        view.add("rows", Arrays.asList("<tr><td>Louis</td><td>Armstrong</td></tr>", "<tr><td>Benny</td><td>Goodman</td></tr>"));
        Assert.assertEquals("<table><tr><td>Louis</td><td>Armstrong</td></tr><tr><td>Benny</td><td>Goodman</td></tr></table>", view.render());
    }

    @Test
    public void testView() {
        View view = new View("<table>{rows}</table>");

        View row1 = new View("<tr><td>{firstName}</td><td>{lastName}</td></tr>");
        row1.add("firstName", "Louis");
        row1.add("lastName", "Armstrong");
        View row2 = new View("<tr><td>{firstName}</td><td>{lastName}</td></tr>");
        row2.add("firstName", "Benny");
        row2.add("lastName", "Goodman");

        view.add("rows", Arrays.asList(row1, row2));
        Assert.assertEquals("<table><tr><td>Louis</td><td>Armstrong</td></tr><tr><td>Benny</td><td>Goodman</td></tr></table>", view.render());
    }

但是,我在运行测试时遇到错误,而且我不确定如何解决问题。

我注意到发生的事情是,不是简单地放置一个支架[在项目周围替换字符串,而是放两个。

这是我得到的错误:

org.junit.ComparisonFailure: expected:<<table>[<tr><td>Louis</td><td>Armstrong</td></tr><tr><td>Benny</td><td>Goodman</td></tr>]</table>> but was:<<table>[[<tr><td>Louis</td><td>Armstrong</td></tr>, <tr><td>Benny</td><td>Goodman</td></tr>]]</table>>
    at org.junit.Assert.assertEquals(Assert.java:115)

如果你看,它说它期望[<tr><td>Louis...,而是获得[[<tr><td>Louis...

我不确定如何解决这个问题,所以如果有人请指出我正确的方向。

1 个答案:

答案 0 :(得分:0)

您的问题是,您在测试中传递的String的{​​{1}}表示形式不符合您的预期。

如果您运行此代码

List

它将输出到控制台

List list = Arrays.asList("<p>foo</p>", "<p>bar</p>");
System.out.println(list.toString());

在您的测试中,您希望它输出HTML而不需要任何进一步的标记,如此

[<p>foo</p>, <p>bar</p>]

要解决此问题,您必须迭代所传递的对象(如果适用)。最简单的方法是更改​​<p>foo</p><p>bar</p> 方法的签名,以便始终可以遍历对象

add

如果这不是一个选项,因为您还将传递非迭代(例如,普通void add(String str, Iterable obj); 对象),您可以重载您的方法。或者,您可以在运行时进行一些自定义类型检查,但这可能会变得非常难看。

编辑:

您可以使用我之前提供的签名添加(而不是替换)方法。对于第二个测试,您需要实现String方法。代码如下:

toString()