2011-12-16 113 views
3

在Java中有沒有相當於php的strtr的函數?在java中相當於php strtr

string strtr (string $str , string $from , string $to) 

如果有三個參數,strtr函數返回字符串的一個副本,其中在$from每個(單字節)字符的所有事件都被翻譯成相應的字符在$to,即,$from[$n]每次發生已替換爲$to[$n],其中$n是兩個參數中的有效偏移量。

回答

5

在JDK中找不到與您的strtr直接等價的內容。在阿帕奇百科全書StringUtils的,有StringUtils.replaceChars

String.replace並不真正適合你的情況,除非你在$from參數中使用它的每個字母,並與$to替代品取代它。不過,使用StringBuilder實現自己的效用函數並自行替換它很容易。這幾乎是StringUtils.replace所做的。

3

您可以在一個循環中調用String.replace(char oldChar, char newChar)。例如:

String from = "abc"; 
String to = "xyz"; 
String str = "abc string"; 
for(int i = 0; i < from.length(); i++) 
    str = str.replace(from.charAt(i), to.charAt(i)); 
0

這是我以前寫的一個實現。歡迎來到它。

public static String strtr(String str, String from, String to) { 
    char[] out = null; 
    for (int i = 0, len = str.length(); i < len; i++) { 
     char c = str.charAt(i); 
     int p = from.indexOf(c); 
     if (p >= 0) { 
      if (out == null) out = str.toCharArray(); 
      out[i] = to.charAt(p); 
     } 
    } 
    return out != null ? new String(out) : str; 
} 
0

我的方法:

public static String strtr(String str, String froms, String tos) 
     {char[] str1=str.toCharArray(); 
      int j; 
      for (int i=0,len=str.length(); i<len; ++i) 
       {j=froms.indexOf(str.charAt(i)); 
       if (j!=-1) 
        {str1[i]=tos.charAt(j); 
        } 
       } 
      return String.valueOf(str1); 
     } 
1

寫了下面的兩種方法,因爲我一直在尋找類似strtr函數的效率功能的東西。只需複製並在你的Java項目中粘貼此代碼,並使用這兩種方法提供(Apache許可證2.0):

使用示例

Map<String, String> replacements = new TreeMap<String, String>(); 
replacements.put("this", "that"); 
replacements.put("that", "this"); 
replacements.put("Nothing much", "Everything"); 

String example = Strtr.replaceStringUsingMap("Whether this or that, whats the difference? Nothing much.", replacements); 

System.out.println(example); 

輸出

輸入字符串:

"Whether this or that, whats the difference? Nothing much." 

輸出字符串:

"Whether that or this, whats the difference? Everything." 

源代碼

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import java.util.TreeMap; 

/** 
* Two public methods can be used, mimicing strtr in php: 
* 
* {@link #replaceStringUsingChars(String, String, String)} 
* 
* {@link #replaceStringUsingMap(String, Map)} 

* Apache 2.0 License 
* 
* @author Basil Musa 
*/ 
public class Strtr { 

    /** 
    * Similar to strtr in php, characters in 'from' will be replaced by characters in 'to' 
    * in the same order character by character. 
    * 
    * @param haystack 
    * @param from 
    * @param to 
    * @return String having the replacements made 
    */ 
    public static String replaceStringUsingChars(String haystack, String from, String to) { 
     if (from.length() != to.length()) { 
      throw new IllegalArgumentException("from and to should have same number of characters."); 
     } 
     Map<String, String> replacements = new HashMap<String, String>(); 
     int length = from.length(); 
     for (int i = 0; i < length; i++) { 
      replacements.put(String.valueOf(from.charAt(i)), String.valueOf(to.charAt(i))); 
     } 
     return replaceStringUsingMap(haystack, replacements); 
    } 

    /** 
    * This method will return a string by replacing all occurrences of keys in needle2replacement occurring in 
    * haystack with the corresponding values. Once a replacement is made, it wont be replaced again. 
    * 
    * The method will start with the longest keys first. 
    * Keys of "" (empty strings) will be ignored. 
    * 
    * If the map is empty, the method returns the same haystack String directly. 
    * 
    * @param haystack The string to be replaced 
    * @param needle2replacement The map of keys to search and values to be replaced 
    * @return String containing haystack with all the replacements in needle2replacement made 
    */ 
    public static String replaceStringUsingMap(String haystack, Map<String, String> needle2replacement) 
    { 
     // To optimize, just return the haystack if the map has no items 
     if (needle2replacement.isEmpty()) { 
      return haystack; 
     } 

     // Sort map by length of keys please by longest string first 
     Map<String, String> sortedNeedle2replacement = sortKeysByLengthDescending(needle2replacement); 

     Set<String> arrNeedles = sortedNeedle2replacement.keySet(); 
     List<Range> ranges = new ArrayList<>(); 

     int lengthDifference = 0; 
     for (String needle : arrNeedles) { 

      int indexOf = -1; 

      // Ignore needles whom are empty strings 
      if (needle.equals("")) { 
       continue; 
      } 

      while(-1 != (indexOf = haystack.indexOf(needle, indexOf + 1))) { 
       String replacement = sortedNeedle2replacement.get(needle); 
       if (replacement == null) { 
        throw new IllegalArgumentException("Map value of null found in key ['" + needle + "']"); 
       } 

       Range range = new Range(indexOf, indexOf + needle.length() - 1, needle, replacement); 

       // Check for any overlaps 
       boolean addRange = true; 
       for (Range target : ranges) { 
        if (range.isOverlappingWith(target)) { 
         addRange = false; 
         break; 
        } 
       } 
       if (addRange) { 
        ranges.add(range); 
        lengthDifference += range.replacement.length() - range.needle.length(); 
       } 
      } 
     } 

     // Sort ranges please 
     Collections.sort(ranges, new Comparator<Range>() { 
      @Override 
      public int compare(Range o1, Range o2) { 
       return o1.begin - o2.begin; 
      } 
     }); 

     // type them 
     StringBuilder stringBuilder = new StringBuilder(haystack.length() + lengthDifference); 

     int startAt = 0; 
     for (Range range : ranges) { 
      stringBuilder.append(haystack.substring(startAt, range.begin)); 
      stringBuilder.append(range.replacement); 
      startAt = range.end + 1; 
     } 
     stringBuilder.append(haystack.substring(startAt)); 

     return stringBuilder.toString(); 
    } 

    private static class Range 
    { 
     public Range(int begin, int end, String needle, String replacement) { 
      super(); 
      if (begin > end) { 
       throw new RuntimeException("begin [" + begin + "] should be smaller or equal to end [" + end + "]"); 
      } 
      this.begin = begin; 
      this.end = end; 
      this.needle = needle; 
      this.replacement = replacement; 
     } 

     public final int begin; 
     public final int end; 
     public final String needle; 
     public final String replacement; 

     public String toString() { 
      return String.format("{%d,%d,%s,%s}", begin, end, needle, replacement); 
     } 

     /** 
     * @param target 
     * @return 
     */ 
     public boolean isOverlappingWith(Range target) { 
      final boolean liesBefore = this.end < target.begin; 
      final boolean liesAfter = this.begin > target.end; 
      if (liesBefore || liesAfter) { 
       return false; 
      } 
      return true; 
     } 

     /** 
     * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
     *    XXXXXX 
     *   YYYYYYYYYYYYYYYY 
     *   
     * Y is surround X as shown above 
     * 
     * @param target 
     * @return 
     */ 
     public boolean isSurrounding(Range target) { 
      if (this.begin < target.begin && this.end > target.end) { 
       return true; 
      } 
      return false; 
     } 
    } 


    private static Map<String, String> sortKeysByLengthDescending(
      Map<String, String> needle2replacement) { 
     Map<String, String> sortedNeedle2replacement = new TreeMap<String, String>(new Comparator<String>() { 
      @Override 
      public int compare(String s1, String s2) { 
       if (s1.length() > s2.length()) { 
        return -1; 
       } else if (s1.length() < s2.length()) { 
        return 1; 
       } else { 
        return s1.compareTo(s2); 
       } 
      } 
     }); 
     sortedNeedle2replacement.putAll(needle2replacement); 

     return sortedNeedle2replacement; 
    } 
}