我需要一些帮助才能将替换所有功能添加到我的Flex项目中。我希望以尽可能自然的方式做到这一点。
我想要实现的是能够运行此代码(使用Flex编译器)"aabbaaba".replaceAll("b","c")
并获取"aaccaaca"
。我还希望链接replaceAll
个电话
注意:我实际上不会用b
替换c
s,而是在编码时不知道的各种字符串!
我不想要的:
1.使用带有全局标志的正则表达式。要替换的令牌是根据广告运行时间确定的,并将它们转换为正则表达式并不是直截了当的
2.使用StringUtil.replace
方法。这是一种静态方法,链条很难看
3.链split
和join
。因为在阅读代码时可能会让其他人感到困惑
4.禁用严格类型检查。我想对我的其余代码进行类型检查。
这是我到目前为止所做的:
String.prototype.replaceAll = function(replace:String, replaceWith:String):String{
return this.split(replace).join(replaceWith);
}
可以像这样调用:
"aababacaaccb"["replaceAll"]("b", "c")["replaceAll"]("c", "a");
此外,是否有任何建议反对通过原型扩展对象? 我也会接受一个强烈反对通过原型扩展String对象的答案。
谢谢你,
阿林
答案 0 :(得分:7)
第二个答案是:
为String编写包装器类StringEx,您可以将replaceAll定义为像这样链接
public function replaceAll(replace:String, replaceWith:String):StringEx {
string = string.replace(new RegExp(replace, 'g'), replaceWith);
return this;
}
通过提供toString(),您可以轻松地将StringEx对象更改为String
var result:String = "" + new StringEx("aaccaaca").replaceAll('b', 'c').replaceAll('c', 'a');
你可以在这里获得完整版:OOP way of prototype extension - wonderfl build flash online
答案 1 :(得分:2)
我认为您可以获得所有技术答案。我将详细阐述我认为最适合这种语言的方法。
不建议在诸如AS3的OOP语言中使用原型(主要是因为它们无视封装)。你暗示你不想要“混淆别人”的东西(与split.join有关);好吧,AS3中的原型非常令人困惑。 就像这样一个例子,原型声明可以在代码中的任何地方完成,因此它应该驻留在哪里并不明显。如果“其他人”在你的代码中遇到“foo”.replaceAll(),那么找到那个方法并检查它的真正作用并不是很明显。
静态功能修正了这一点并且很简单。当然,你需要一个额外的论点,你不能真正地正确链接,但这是一件坏事吗?
如果你需要性能,split.join就是你要走的路。我敢打赌,更多的AS3开发者知道split.join而不是使用原型。
另一方面,我认为最具语义和实用的方法是使用自己的语言方法(因此我之前的答案)。您正在尝试用AS3中的另一个字符串替换字符串中的所有针,并且为此语言具有带有全局标志的String :: replace方法。我很确定有一种方法可以在regexp中轻松解析和使用任何字符串。
我同意在某些情况下可能需要辅助方法(如replaceAll),但我强烈建议您不要使用原型,而是使用更标准的方法,如StringUtil.replace。
答案 2 :(得分:1)
我不想要的: 1.使用带有全局标志的正则表达式
为什么不呢?对于简单的字符串替换来说非常简单直观且具有高性能:
"aababacaaccb".replace(/b/g, "c");
或者如果您愿意:
var needle:String="b";
"aababacaaccb".replace(new RegExp(needle,"g"), "c");
我不建议使用原型,它不是非常OOP也不是标准......对于这样一个简单的操作来说感觉太糟糕了。
答案 3 :(得分:1)
我无法想到满足您发布的4项要求的方法。但我认为如果您的主要目标是一次性替换各种令牌(您希望通过链接调用实现的目标),同时能够使用任何字符串作为令牌,您可以尝试这样的事情:
public class StringUtil {
public static function replaceAll(source:String,map:Object):String {
for(var replaceToken:String in map) {
source = source.split(replaceToken).join(map[replaceToken]);
}
return source;
}
}
var str:String = "a1ccca111a";
str = StringUtil.replaceAll(str,{
'a' : 'b',
'1' : '2'
});
trace(str);
要记住一点需要注意。使用Object对象时,不保证顺序。在大多数情况下,这并不重要,但如果在您的情况下,则可以使用数组,并在每个插槽中存储令牌及其替换(例如,作为对象)。
答案 4 :(得分:0)
"aabbaaba".split('b').join('c')
返回'aaccaaca'
UPD:
我想知道为什么它对你来说是不可接受的(但是它不支持正则表达式):它的工作速度非常快(在严格的循环中检查它)并且完全符合你的要求。
还有一些解决方案在你的黑名单中没有提到(btw静态功能比使用原型 - imho更好):
replaceAll
方法和super()
调用即可扩展String类。如果您选中true
(myStringInstance is String)
答案 5 :(得分:0)
我有两个答案。第一个是你想要的。但我推荐第二个。
在flex中启用原型非常简单,可以通过设置flex-config
来完成ReplaceAllTest.as
package {
import flash.display.Sprite;
import flash.text.TextField;
public class ReplaceAllTest extends Sprite
{
public function ReplaceAllTest()
{
var tf:TextField = new TextField;
String.prototype.replaceAll = function(replace:String, replaceWith:String):String{
return this.split(replace).join(replaceWith);
}
// now the strict mode is off compiler does NOT warn the following code
tf.text = "aababacaaccb".replaceAll("b", "c")
.replaceAll("c", "a");
addChild(tf);
}
}
}
ReplaceAllTest-config.xml中
<?xml version="1.0" encoding="utf-8" ?>
<flex-config>
<compiler>
<as3>false</as3>
<es>true</es>
<strict>false</strict>
</compiler>
<static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
</flex-config>
我仍然不鼓励这种方式,因为启用原型设置并关闭严格模式会降低代码速度。
答案 6 :(得分:0)
我知道这是一个旧线程,但这是我想出的,可以做任何常规字符串。
public static function replaceAll(p_string:String, p_search:String, p_replaceWith:String):String{
//Dummy Control
if(p_string == null)
return '';
//Iterates through the string from right to left so we don't go over what we are changing.
var index:int = p_string.lastIndexOf(p_search);
while(index != -1){
//Splits the string at the index
p_string = p_string.slice(0, index) + p_replaceWith + p_string.slice(index+p_search.length);
//Attempts to find the next index
index = p_string.lastIndexOf(p_search, index-1);//We -1 so we always move down the line
}
//Returns the modified p_string
return p_string;
}