簡體   English   中英

Java:用隨機字符串替換字符串的最簡單方法

[英]Java: Easiest way to replace strings with random strings

字符串將由某些符號(例如,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中? 如果是這樣,我應該使用哪種方法?

要回答第一個問題:不。

由於您正在執行隨機替換,因此正則表達式將無濟於事,因此關於正則表達式的所有內容都是隨機的。 *由於您的字符串位於數組中,因此您無需使用任何模式匹配就可以找到它們,因此再次不需要使用正則表達式。

**編輯:問題已被編輯,因此不再顯示字符串在數組中。 在這種情況下,假設它們都在一個大字符串中,則可以構建一個正則表達式來查找要替換的部分,如其他答案所示。*

我認為這是從包含超符號的字符串中替換某些符號集的最干凈的解決方案。 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();
}

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

因為你需要面前讓盡可能多的替代品加入令牌重新走到一起。

這里有兩個看似棘手的部分。 首先,嘗試捕獲以識別那些不是整數的標記。 我建議您將該部分放到它自己的方法中,因為它可以工作,但是有點不客氣。

第二個是我設置source變量和target變量的位置。 我在這里所做的事情是獲得一個隨機選擇的非數字符號之一的索引 一旦有了兩個隨機索引,就可以在下一行交換它們。

一種替代方法是,在將原始String拆分為數組之后,從隨機選擇的符號中構建新的String。

  1. 是的,可以使用正則表達式來完成。 可能不是很漂亮,不是沒有一兩個循環
  2. 是的,這可以用Java實現。
  3. 參見Randomregex
  4. 該實施留給學生練習。

謝謝一群人。 這是我想出的。 看看是否可以提出一種更有效的方法。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM