如何在Java中创建文章微调器正则表达式?

时间:2010-08-03 03:36:16

标签: java regex spinner article

比方说,我想采用这句话:

  

{{Hello | What's Up | Howdy} {world | planet} |   {再见|后来}   {人|市民|居民}}

并随机将其变为以下之一:

Hello world
Goodbye people
What's Up word
What's Up planet
Later citizens
etc.

基本思想是在每对括号内包含无限数量的选项,用“|”分隔。该程序需要经历并随机为每组括号选择一个选项。请记住,大括号可以在彼此之间无限地嵌套。我发现了一个关于这个的线程并尝试将其转换为Java,但它没有用。这是可能有用的python代码:

import re
from random import randint

def select(m):
    choices = m.group(1).split('|')
    return choices[randint(0, len(choices)-1)]

def spinner(s):
    r = re.compile('{([^{}]*)}')
    while True:
        s, n = r.subn(select, s)
        if n == 0: break
    return s.strip()

这是我尝试将Python代码转换为Java。

public String generateSpun(String text){
    String spun = new String(text);
    Pattern reg = Pattern.compile("{([^{}]*)}");
    Matcher matcher = reg.matcher(spun);
    while (matcher.find()){
       spun = matcher.replaceFirst(select(matcher.group()));
    }
    return spun;
}

private String select(String m){
    String[] choices = m.split("|");
    Random random = new Random();
    int index = random.nextInt(choices.length - 1);
    return choices[index];
}

不幸的是,当我尝试通过调用

进行测试时
generateAd("{{Hello|What's Up|Howdy} {world|planet} | {Goodbye|Later} {people|citizens|inhabitants}}");

在我的程序的主要部分,它在generateSpun中的行中给出了一个错误,其中声明了Pattern reg,给了我一个PatternSyntaxException。

java.util.regex.PatternSyntaxException: Illegal repetition
{([^{}]*)}

有人可以尝试创建一个可以做我想做的Java方法吗?

4 个答案:

答案 0 :(得分:1)

以下是您当前代码的一些问题:

  • 您应该重复已编译的Pattern,而不是每次<{1}}
  • 您应该重复您的Pattern.compile,而不是每次<{1}}
  • 请注意,String.split是基于正则表达式的,因此您必须Random
  • 请注意,必须将Java正则表达式中的花括号转义为字面匹配,因此new Random
  • 您应该查询split("\\|"),而不是Pattern.compile("\\{([^{}]*)\\}");,默认为群组group(1)
  • 您使用group()错误,请查找Matcher.appendReplacement/Tail而不是
  • Random.nextInt(int n)独占上限(就像Java中的许多此类方法一样)
  • 算法本身实际上不能正确处理任意嵌套的大括号

请注意,转义是通过前面的0完成的,并且作为Java字符串文字需要加倍(即replaceFirst包含单个字符,反斜杠)。

附件

答案 1 :(得分:0)

要修复正则表达式,请在外部{}之前添加反斜杠。这些是Java正则表达式中的元字符。但是,我认为这不会导致工作计划。在将变量绑定到正则表达式后,您正在修改变量spun,并且我认为返回的匹配器不会反映更新的值。

我也不认为python代码适用于嵌套选择。你真的尝试过python代码吗?你说它“应该有效”,但在花费大量时间将它移植到Java之前验证它是明智的。

答案 2 :(得分:0)

好吧,我刚在PHP&amp; Python,这里演示http://spin.developerscrib.com,它处于非常早期阶段,因此可能无法期待,源代码在github上:https://github.com/razzbee/razzy-spinner

答案 3 :(得分:0)

使用它,会起作用......我做了,并且工作得很好

Pattern p = Pattern.compile("cat");
 Matcher m = p.matcher("one cat two cats in the yard");
 StringBuffer sb = new StringBuffer();
 while (m.find()) {
     m.appendReplacement(sb, "dog");
 }
 m.appendTail(sb);
 System.out.println(sb.toString());

在这里

private String select(String m){
    String[] choices = m.split("|");
    Random random = new Random();
    int index = random.nextInt(choices.length - 1);
    return choices[index];
}

m.split("|")使用m.split("\\|")

其他明智的做法是将每个角色分成每个角色

并使用Pattern.compile("\\{([^{}]*)\\}");