使用java和Android提取bbcode引用但不提取引号标记内的内容

时间:2013-12-01 14:59:24

标签: java regex string bbcode

我将使用引号提取bbcode,但在实际输出即将到来时无效。

我想实现bbcode解析模块,用于提取引号作为所需的输出。引号的数量应该是递归方法或其他一些方法。

INput : 

Testing [quote]http://www.yourube.com?watch?v=asasdsadsa [url] aisa [/url] [/quote] Testing 

   Desired Output

测试     http://www.yourube.com?watch?v=asasdsadsa [url] aisa [/ url]      AISA 测试

Actual Output:

http://www.yourube.com?watch?v=asasdsadsa [url] aisa [/url]
http://www.yourube.com?watch?v=asasdsadsa  aisa 

以下是我的代码

        String s = "[quote]http://www.yourube.com?watch?v=asasdsadsa [url] aisa [/url][/quote]";
        String t = bbcode(s);
        System.out.println(t);
        String u = bbcode2(t);
        System.out.println(u);

 public static String bbcode(String text) {
        String html = text;

        HashMap<String,String> bbMap = new HashMap<String , String>();


        bbMap.put("\\[quote\\](.+?)\\[/quote\\]", "$1");


        for (Map.Entry entry: bbMap.entrySet()) {
            html = html.replaceAll(entry.getKey().toString(), entry.getValue().toString());
        }

        return html;
    }

       public static String bbcode2(String text) {
        String html = text;

        HashMap<String,String> bbMap = new HashMap<String , String>();



        bbMap.put("\\[quote\\](.+?)\\[/quote\\]", "$1");

        bbMap.put("\\[url\\](.+?)\\[/url\\]", "$1");

        for (Map.Entry entry: bbMap.entrySet()) {
            html = html.replaceAll(entry.getKey().toString(), entry.getValue().toString());
        }

        return html;
    }

2 个答案:

答案 0 :(得分:1)

这是匹配BB代码对的通用Java正则表达式:

\\[([^\\]]+)\\](.+?)\\[/\\1\\]

这将获得顶级匹配,例如在[a][b] hi [/b] hello [/a][c] yo [/c]中,第2组将匹配[b] hi [\b] helloyo。 (Demonstrated here


在我看来,任何正则表达式解决方案都要求你使用递归(在正则表达式之外)来查找所有匹配项。你将不得不找到所有顶级匹配(将它们添加到某个数组),然后递归地在每个匹配上使用相同的正则表达式(将它们全部添加到相同的结果数组),直到最终没有匹配可以找到更多匹配

在该示例中,您可以看到您需要再次在[b] hi [\b] hello上运行正则表达式,以返回[b] hi [/b] hi的内容。

例如,输入:

[A] outer [B] [C] last one left [/C] middle [/B] [/A]  [A] out [B] in [/B] [/A]

首先,对该字符串运行正则表达式并查看组2匹配:

outer [B] [C] last one left [/C] middle [/B]
out [B] in [/B]

将这些添加到结果数组中,然后针对这些匹配运行正则表达式并获取:

 [C] last one left [/C] middle
 in

将这些添加到结果数组中,然后再针对这些匹配运行它并获取:

 last one left
 [no matches]

最后你会针对last one left运行它而不再获得匹配,所以你已经完成了。

Raju,如果你不熟悉递归,那么在这一点上停止阅读并尝试自己解决问题将是非常有益的 - 如果你放弃就回来吧。那说......


此问题的Java解决方案是:

public static void getAllMatches(Pattern p, String in, List<String> out) {
  Matcher m = p.matcher(in);           // get matches in input
  while (m.find()) {                   // for each match
    out.add(m.group(2));               // add match to result array
    getAllMatches(p, m.group(2), out); // call function again with match as input
  }
}

And here is a working example on ideone

ideone输出:

[A]outer[B][C]last one left[/C]middle[/B][/A] [A]out[B]in[/B][/A]
-----------
- outer[B][C]last one left[/C]middle[/B]
- [C]last one left[/C]middle
- last one left
- out[B]in[/B]
- in

[quote]http://www.yourube.com?watch?v=asasdsadsa [url]aisa[/url] [/quote]
-----------
- http://www.yourube.com?watch?v=asasdsadsa [url]aisa[/url] 
- aisa

答案 1 :(得分:0)

不是最好的方式,而是一种非注册方式......

int lastIndex = 0;
String startString = "[quote]";
String endString = "[/quote]";
int start;
int end;
while (lastIndex != -1) {
   start = string.indexOf(startString, lastIndex);
   lastIndex = start;
   if (lastIndex == -1) {
      break;
   }
   end   = string.indexOf(endString, lastIndex);
   lastIndex = end;
   if (lastIndex == -1) {
      break;
   }
   System.out.println(string.substring(
       start  + startString.length,
       end + 1));
}