如何在Java中创建文章微调器正则表达式?
比方说,我想采用这句话:
{{Hello | What’s Up | Howdy} {world | planet} | {再见|稍后} {people | citizens | inhabitants}}
并随机将其变为以下之一:
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方法吗?
以下是您当前代码的一些问题:
- 您应该每次都重用已编译的
Pattern
而不是Pattern.compile
- 你应该每次 重复使用
Random
而不是new Random
- 请注意,
String.split
是基于regex的,因此必须split("\\|")
- 请注意,必须将Java正则表达式中的花括号转义为字面匹配,因此
Pattern.compile("\\{([^{}]*)\\}");
- 您应该查询
group(1)
,而不是group()
,默认为group0
- 您正在使用
replaceFirst
错误,请查找Matcher.appendReplacement/Tail
-
Random.nextInt(int n)
具有独占上限 (与Java中的许多此类方法一样) - 算法本身实际上不能正确处理任意嵌套的括号
请注意,转义是通过在\
前面完成的,并且作为Java字符串文字,它需要加倍(即"\\"
包含单个字符,反斜杠)。
附件
- 具有上述修复的源代码和输出,但算法没有重大改变
要修复正则表达式,请在外部{
和}
之前添加反斜杠。 这些是Java正则表达式中的元字符。 但是,我认为这不会导致工作计划。 在绑定到正则表达式后,您正在修改变量spun
,我不认为返回的匹配器将反映更新的值。
我也不认为python代码适用于嵌套选择。 你真的尝试过python代码吗? 你说它“应该有效”,但在花费大量时间将它移植到Java之前validation它是明智的。
好吧,我刚刚在PHP和Python中创建了一个,在这里演示http://spin.developerscrib.com ,它在很早的阶段,所以可能无法期望,源代码在github上: https : //github.com / razzbee / razzy微调
使用它,会起作用……我做了,并且工作得很好
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("\\{([^{}]*)\\}");