Java: самый простой способ заменить строки случайными строками - PullRequest
2 голосов
/ 26 октября 2008

Строка будет состоять из определенных символов (например, ax, bx, dx, c, acc) и чисел.

например: топор 5 5 дх 3 акк с топором bx

Я хочу заменить один или все символы (случайным образом) другим символом из того же набора. т. е. заменить одну из {ax, bx, dx, c, acc} на одну из {ax, bx, dx, c, acc}.

пример замены: согласно 5 5 дх 3 акк c ax bx или же с 5 5 дх 3 акк топор с топором

Есть ли способ сделать это с помощью регулярных выражений? На яве? Если да, то какие методы мне следует использовать?

Ответы [ 5 ]

1 голос
/ 26 октября 2008

Я думаю, что это самое чистое решение для замены определенного набора символов из строки, содержащей их расширенный набор. Приложение является ключевым к этому методу. Одно важное предостережение: не включайте никакие символы доллара ($) в ваш список элементов. избежать их с помощью "\ $" в конечном итоге использовать
.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();
}
1 голос
/ 26 октября 2008

Для ответа на первый вопрос: нет.

Поскольку вы делаете случайную замену, регулярное выражение не поможет вам, ничто в регулярном выражении не является случайным. * Поскольку ваши строки находятся в массиве, вам не нужно находить их с каким-либо сопоставлением с образцом, поэтому повторное выражение не требуется.

** Редактировать: вопрос был отредактирован, поэтому в нем больше не говорится, что строки находятся в массиве. В этом случае, предполагая, что все они находятся в одной большой строке, вы можете создать регулярное выражение для поиска частей, которые вы хотите заменить, как показано в других ответах. *

0 голосов
/ 26 октября 2008

спасибо, ребята. вот что я придумал. посмотрим, сможете ли вы придумать более эффективный способ.

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;
}
0 голосов
/ 26 октября 2008
  1. Да, это можно сделать с помощью регулярных выражений. Наверное, не очень красиво, не без петли или двух
  2. Да, это может быть реализовано в Java.
  3. См. Случайная , регулярное выражение пакет
  4. Реализация оставлена ​​в качестве упражнения для студента.
0 голосов
/ 26 октября 2008

Используйте класс Случайный , чтобы сгенерировать случайное целое число для выбора индекса символов.

    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);

Сделайте столько замен, сколько вам нужно до вы присоедините токены обратно.

Здесь есть две части, которые могут показаться сложными. Во-первых, попытка catch идентифицирует те токены, которые не являются целыми числами. Я рекомендую вам использовать эту часть в своем собственном методе, поскольку она работает, но она немного хакерская.

Во-вторых, я устанавливаю переменные source и target. То, что я делаю там, это получение случайно выбранного индекса одного из нечисловых символов. Если у меня есть два случайных индекса, я могу поменять их местами в следующей строке.

Альтернативой может быть создание новой строки из случайно выбранных символов после разделения исходной строки на массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...