字符串将由某些符号(例如ax,bx,dx,c,acc)和数字组成。
例如: ax 5 5 dx 3 acc c ax bx
我想用同一组的另一个符号替换一个或所有符号(随机)。即,用{ax,bx,dx,c,acc}中的一个替换{ax,bx,dx,c,acc}中的一个。
替换示例: acc 5 5 dx 3 acc c ax bx 要么 c 5 5 dx 3 acc c ax ax
有没有办法用正则表达式做到这一点?在Java?如果是这样,我应该使用哪种方法?
答案 0 :(得分:1)
回答第一个问题:不。
由于你正在做一个随机替换,正则表达式不会帮助你,关于正则表达式的任何内容都是随机的。 *由于你的字符串是一个数组,你不需要找到任何模式匹配,所以再次正则表达式是没有必要的。
**编辑:问题已被编辑,因此不再说字符串在数组中。在这种情况下,假设它们都在一个大字符串中,您可以构建一个正则表达式来查找要替换的部分,如其他答案所示。*
答案 1 :(得分:1)
我认为这是从包含超集的字符串中替换某些符号集的最干净的解决方案。
appendreplacement是这种方法的关键。
一个重要的警告:不要在元素列表中包含任何未使用的美元字符($)。使用“\ $”逃避它们
最终使用
.replaceall( “\ $”, “\\ $”);
在将每个字符串添加到列表之前。
另见javadoc对$符号的疑问。
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ReplaceTokens {
public static void main(String[] args) {
List<String> elements = Arrays.asList("ax", "bx", "dx", "c", "acc");
final String patternStr = join(elements, "|"); //build string "ax|bx|dx|c|acc"
Pattern p = Pattern.compile(patternStr);
Matcher m = p.matcher("ax 5 5 dx 3 acc c ax bx");
StringBuffer sb = new StringBuffer();
Random rand = new Random();
while (m.find()){
String randomSymbol = elements.get(rand.nextInt(elements.size()));
m.appendReplacement(sb,randomSymbol);
}
m.appendTail(sb);
System.out.println(sb);
}
/**
* this method is only needed to generate the string ax|bx|dx|c|acc in a clean way....
* @see org.apache.commons.lang.StringUtils.join for a more common alternative...
*/
public static String join(List<String> s, String delimiter) {
if (s.isEmpty()) return "";
Iterator<String> iter = s.iterator();
StringBuffer buffer = new StringBuffer(iter.next());
while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
return buffer.toString();
}
答案 2 :(得分:0)
使用Random类生成随机int以选择符号的索引。
String text = "ax 5 5 dx 3 acc c ax bx";
System.out.println("Original: " + text);
String[] tokens = text.split(" ");
List<Integer> symbols = new ArrayList<Integer>();
for(int i=0; i<tokens.length; i++) {
try {
Integer.parseInt(tokens[i]);
} catch (Exception e) {
symbols.add(i);
}
}
Random rand = new Random();
// this is the part you can do multiple times
int source = symbols.get((rand.nextInt(symbols.size())));
int target = symbols.get((rand.nextInt(symbols.size())));
tokens[target] = tokens[source];
String result = tokens[0];
for(int i=1; i<tokens.length; i++) {
result = result + " " + tokens[i];
}
System.out.println("Result: " + result);
在你将join令牌重新组合在一起之前,根据需要进行多次替换。
这里有两个部分可能看起来很棘手。首先,try catch来识别那些不是整数的标记。我建议你把那个部分拉出来用它自己的方法,因为它有效,但它有点hacky。
第二个是我设置source
和target
变量的地方。我正在做的是获取一个非数字符号的随机选择的索引。一旦我有两个随机索引,我可以在下一行交换它们。
另一种方法是,在将原始String拆分为数组后,从随机选择的符号中构建一个新的String。
答案 3 :(得分:0)
答案 4 :(得分:-1)
private final String[] symbolsPossible = {"ax","bx","cx","dx","foo"};
private boolean exists;
private final String mutate(String s)
{
String[] tokens=s.split(" ");
for(int j=0; j<tokens.length; j++)
if(Math.random()<.1) //10% chance of mutation per token
{
//checking to see if the token is a supported symbol
exists=false;
for(int i=0; i<symbolsPossible.length; i++)
if(tokens[j].equals(symbolsPossible[i]))
exists=true;
if(exists)
tokens[j]=symbolsPossible[(int)Math.random()*symbolsPossible.length];
}
StringBuffer result=new StringBuffer();
for(String t:tokens)
result.append(t);
return result;
}