Джава:Самый простой способ заменить строки случайными строками
Вопрос
Строка будет состоять из определенных символов (например, ax,bx,dx,c,acc) и цифр.
бывший:AX 5 5 DX 3 ACC C AX BX
Я хочу заменить один или все символы (случайным образом) другим символом того же набора.т. е. замените один из {ax,bx,dx,c,acc} на один из {ax,bx,dx,c,acc}.
пример замены:АКК 5 5 dx 3 акк c ax bx или c 5 5 dx 3 акк c ax ax
Есть ли способ сделать это с помощью регулярных выражений?На Яве?Если да, то какие методы мне следует использовать?
Решение
Я думаю, что это наиболее чистое решение для замены определенного набора символов из строки, содержащей их надмножество.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();
}
Другие советы
Чтобы ответить на первый вопрос:нет.
Поскольку вы выполняете случайную замену, регулярное выражение вам не поможет, в регулярном выражении нет ничего случайного.* Поскольку ваши строки находятся в массиве, вам не нужно находить их с помощью какого-либо сопоставления с образцом, поэтому регулярное выражение снова не требуется.
**Редактировать:вопрос был отредактирован, поэтому в нем больше не говорится, что строки находятся в массиве.В этом случае, предполагая, что все они находятся в одной большой строке, вы можете создать регулярное выражение, чтобы найти части, которые хотите заменить, как показано в других ответах.*
- Да, это можно сделать с помощью регулярных выражений.Наверное, не очень красиво, нет. без петли или двух
- Да, это можно реализовать на Java.
- Видеть Случайный, регулярное выражение упаковка
- Реализация оставлена в качестве упражнения для студента.
Использовать Случайный класс для генерации случайного целого числа для выбора индекса символов.
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);
Сделайте столько замен, сколько вам нужно до ты присоединиться жетоны снова вместе.
Здесь есть две части, которые могут показаться сложными.Во-первых, попытайтесь поймать те токены, которые не являются целыми числами.Я рекомендую вам выделить эту часть в отдельный метод, поскольку она работает, но немного хаотично.
Во-вторых, я установил source
и target
переменные.Что я там делаю, так это получаю случайно выбранный индекс одного из нечисловых символов.Если у меня есть два случайных индекса, я могу поменять их местами в следующей строке.
Альтернативой может быть создание новой строки из случайно выбранных символов после того, как вы разделили исходную строку на массив.
спасибо большое, ребята.вот что я придумал.посмотрим, сможете ли вы придумать более эффективный способ.
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;
}