将replaceAll方法添加到ActionScript String类

时间:2010-11-03 09:18:27

标签: flex actionscript-3 oop actionscript

我需要一些帮助才能将替换所有功能添加到我的Flex项目中。我希望以尽可能自然的方式做到这一点。

我想要实现的是能够运行此代码(使用Flex编译器)"aabbaaba".replaceAll("b","c")并获取"aaccaaca"。我还希望链接replaceAll个电话 注意:我实际上不会用b替换c s,而是在编码时不知道的各种字符串!

我不想要的:
1.使用带有全局标志的正则表达式。要替换的令牌是根据广告运行时间确定的,并将它们转换为正则表达式并不是直截了当的 2.使用StringUtil.replace方法。这是一种静态方法,链条很难看 3.链splitjoin。因为在阅读代码时可能会让其他人感到困惑 4.禁用严格类型检查。我想对我的其余代码进行类型检查。


这是我到目前为止所做的:

String.prototype.replaceAll = function(replace:String, replaceWith:String):String{
    return this.split(replace).join(replaceWith);
}

可以像这样调用:

"aababacaaccb"["replaceAll"]("b", "c")["replaceAll"]("c", "a");

此外,是否有任何建议反对通过原型扩展对象? 我也会接受一个强烈反对通过原型扩展String对象的答案。

谢谢你,
阿林

7 个答案:

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