1

比如说我想用这个短语:

{{Hello|What's Up|你好} {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}}");

在我的程序的主体中,它在声明 Pattern reg 的 generateSpun 行中给了我一个错误,给了我一个 PatternSyntaxException。

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

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

4

4 回答 4

1

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

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

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

附件

于 2010-08-03T04:13:48.380 回答
0

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

我也不认为 python 代码适用于嵌套选择。你真的尝试过python代码吗?您说它“据说可以工作”,但在您花费大量时间将其移植到 Java 之前验证这一点是明智的。

于 2010-08-03T04:09:00.863 回答
0

好吧,我刚刚在 PHP & Python 中创建了一个,演示在这里http://spin.developerscrib.com,它处于非常早期的阶段所以可能无法达到预期,源代码在 github 上:https ://github.com /razzbee/razzy-spinner

于 2016-04-25T03:46:30.353 回答
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("\\{([^{}]*)\\}");

于 2017-04-22T07:27:11.300 回答