【问题标题】:Extracting bbcode quote using java and Android but not extracting the content within the quote tag使用java和Android提取bbcode报价但不提取报价标签内的内容
【发布时间】:2013-12-01 14:59:23
【问题描述】:

我将提取带有引号的 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] 艾萨 测试

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;
    }

【问题讨论】:

  • 你是在解析html吗?
  • 不,我使用“$1”提取标签内的原始内容
  • 你能解释一下这个程序应该做什么吗?
  • 请阅读输入并希望输出。我将用bbcode解析内容,提取bbcode所包含的所有内容进行内容管理
  • 你的问题是bbcode2()吗?

标签: java regex string bbcode


【解决方案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

【讨论】:

  • Raju,我已经在我的答案中添加了工作代码,但是如果您对递归概念完全陌生,我强烈建议您先尝试自己解决这个问题!这是一个有用的东西。
  • 在递归正则表达式匹配方面,使用递归似乎可以减轻很多处理错误。所以...如果我的消息最后有一些任意字符串(无论如何都不是 bbocde 结束标签),我必须构造正则表达式以分成两组,一组用于嵌入 bbcode 中的字符串,一组用于 bbcode 标签之后的任意字符串?
  • 我不确定您的意思,您的最终目标是什么? - 如果解释的时间很长,请将其添加到问题中,一个示例会很有用。
  • 非常感谢您之前的帮助。问题已编辑,OGHaza,我现在正在使用 (.)[^]](.)(]) 和您使用 gskinner.com/RegExr/?37ert 进行测试的工具。一旦成功运行,递归剩余可以拆分标记并添加到输出列表中。
  • 考虑在正则表达式的开头和结尾添加([^\[]*) - 这将捕获 BBCode 之前和之后的文本(由于您在开头添加了一个组,因此组编号将向上移动 1 )。 Like this。请注意,对于大多数匹配,开头的文本将为空白 - 因为它已在上一场匹配结束时被捕获。
【解决方案2】:

不是最简洁的方式,而是一种非正则表达式方式...

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));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2011-08-25
    • 2012-02-13
    • 2017-05-03
    相关资源
    最近更新 更多