2011-01-05 37 views
1

以下(Java)的實現是GDK的一部分:任何Javascript Regex ReplaceAll通過匿名函數實現像Groovy的?

/** 
* Replaces all occurrences of a captured group by the result of a closure on that text. 
* <p/> 
* <p> For examples, 
* <pre> 
*  assert "FOOBAR-FOOBAR-" == "foobar-FooBar-".replaceAll(~"(([fF][oO]{2})[bB]ar)", { Object[] it -> it[0].toUpperCase() }) 
* <p/> 
*  Here, 
*   it[0] is the global string of the matched group 
*   it[1] is the first string in the matched group 
*   it[2] is the second string in the matched group 
* <p/> 
* <p/> 
*  assert "FOO-FOO-" == "foobar-FooBar-".replaceAll("(([fF][oO]{2})[bB]ar)", { x, y, z -> z.toUpperCase() }) 
* <p/> 
*  Here, 
*   x is the global string of the matched group 
*   y is the first string in the matched group 
*   z is the second string in the matched group 
* </pre> 
* <p>Note that unlike String.replaceAll(String regex, String replacement), where the replacement string 
* treats '$' and '\' specially (for group substitution), the result of the closure is converted to a string 
* and that value is used literally for the replacement.</p> 
* 
* @param self a String 
* @param pattern the capturing regex Pattern 
* @param closure the closure to apply on each captured group 
* @return a String with replaced content 
* @since 1.6.8 
* @see java.util.regex.Matcher#quoteReplacement(java.lang.String) 
*/ 
public static String replaceAll(final String self, final Pattern pattern, final Closure closure) { 
    final Matcher matcher = pattern.matcher(self); 
    if (matcher.find()) { 
     final StringBuffer sb = new StringBuffer(self.length() + 16); 
     do { 
      int count = matcher.groupCount(); 
      List<String> groups = new ArrayList<String>(); 
      for (int i = 0; i <= count; i++) { 
       groups.add(matcher.group(i)); 
      } 
      final String replacement = InvokerHelper.toString(closure.call(groups.toArray())); 
      matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); 
     } while (matcher.find()); 
     matcher.appendTail(sb); 
     return sb.toString(); 
    } else { 
     return self; 
    } 
} 

是否有出有Javascript的任何類似的實現?如果不是,自己嘗試實施是否可行;人們會怎麼做呢?

回答

3

我希望我能夠正確理解你的問題,但閱讀示例中的註釋,可以通過js字符串對象的replace方法滿足示例用例。 replace接受一個函數作爲其替代參數:

// true 
console.log(
    "FOOBAR-FOOBAR-" == "foobar-FooBar-".replace(
     /(([fF][oO]{2})[bB]ar)/g, 
     function( all, capture1, capture2) { 
      return all.toUpperCase(); 
     } 
    ) 
); 

// true 
console.log(
    "FOO-FOO-" == "foobar-FooBar-".replace(
     /(([fF][oO]{2})[bB]ar)/g, 
     function(all, capture1, capture2) { 
      return capture2.toUpperCase(); 
     } 
    ) 
); 
+0

哇!我不知道'替換'有這個「過載」!讓我試試看,我會讓你知道它是如何工作的 - 看起來這正是我所要求的。 – 2011-01-05 20:02:04

+0

謝謝@meouw,完美的作品! – 2011-01-05 21:26:21

0

如果你只是想「的replaceAll」一文中給定的字符串,如果我們確定的正則表達式作爲一個全球性的正則表達式,我們可以很容易地更換所有出現在使用Javascript的給定文本中的另一個字符串值內的字符串。

我們如何啓用全局正則表達式就像在正則表達式後面添加「g」標識符一樣簡單。 在正則表達式模式之後使用「g」,內置的javascript替換方法將用新字符串替換給定文本變量的所有匹配項和所有匹配項。

var string_variable; 
string_variable = "Replace text using javascript replace function within a javascript  string variable"; 
string_variable = string_variable.replace(/javascript/g, "js"); 
alert(string_variable); 

正如您在示例javascript代碼中看到的,替換javascript函數的實現或用法非常簡單。

+0

以上的解決方案是,只要你想做簡單的replaceAll就可以在javaScript函數中替換。我想這是你問的。我對嗎? – Ninja 2011-01-05 19:38:12

+0

對不起@Ninja,但這不會。而不是一個替換字符串(在你的例子「js」),我想要使用一個匿名函數,這是爲每個匹配調用,其返回值用於替換(而不是一個字符串的所有替換)。 – 2011-01-05 20:01:07