代码之家  ›  专栏  ›  技术社区  ›  Alin P.

将replaceAll方法添加到ActionScript字符串类

  •  1
  • Alin P.  · 技术社区  · 14 年前

    在将replace all功能添加到Flex项目中时,我需要一些帮助。我宁愿用尽可能自然的方式来做。

    "aabbaaba".replaceAll("b","c") 然后得到 "aaccaaca" replaceAll 电话。
    b s与 c s、 但是各种各样的字符串在编码时是不知道的!

    我不想要的是:
    一。使用带有全局标志的正则表达式。要替换的标记是在运行时确定的,将它们转换为正则表达式并不是直接的。
    2。使用 StringUtil.replace 方法。这是一个静态方法,链接很难看。
    三。链条 split join . 因为在阅读代码时可能会让其他人感到困惑。
    四。禁用严格类型检查。我想对我的其余代码进行类型检查。


    以下是我目前掌握的情况:

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

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

    另外,有没有什么建议反对通过原型扩展对象? 我还将接受一个有强烈理由反对通过原型扩展String对象的答案。

    谢谢您,
    阿林

    7 回复  |  直到 14 年前
        1
  •  2
  •   Cay    14 年前

    我想你得到了所有可能的技术答案。我将详细说明我认为是最好的方式来处理这个语言明智。

    在AS3这样的OOP语言中,不推荐使用原型(主要是因为它们不支持封装)。你暗示你不想让别人感到困惑(关于split.join);好吧,AS3中的原型非常令人困惑。 作为一个例子,原型声明可以在代码中的任何地方完成,因此它应该位于哪里并不明显。如果“其他人”在代码中遇到“foo.replaceAll(),那么在哪里可以找到该方法并检查它的真正功能就一点都不明显了。

    如果需要性能,可以选择split.join。我敢打赌更多的AS3开发人员知道split.join而不是原型的使用。

    另一方面,我认为最具语义和实用性的方法是使用自己的语言方法(因此我之前的答案)。您正在尝试用AS3中的另一个字符串替换字符串中的所有指针,为此,该语言使用带有全局标志的string::replace方法。我确信有一种方法可以轻松地解析和使用regexp中的任何字符串。

        2
  •  7
  •   9re    14 年前

    第二个答案是:

    为String编写包装类StringEx,可以将replaceAll定义为如下链接

    public function replaceAll(replace:String, replaceWith:String):StringEx {
       string = string.replace(new RegExp(replace, 'g'), replaceWith);
       return this;
    }
    

    var result:String = "" + new StringEx("aaccaaca").replaceAll('b', 'c').replaceAll('c', 'a');
    

    您可以在此处获取完整版本: OOP way of prototype extension - wonderfl build flash online

        3
  •  1
  •   Cay    14 年前

    我不想要的是: 一。使用带有全局标志的正则表达式

    为什么不?对于简单的字符串替换来说,这是非常直接和有效的:

    "aababacaaccb".replace(/b/g, "c");
    

    或者如果您愿意:

    var needle:String="b";
    "aababacaaccb".replace(new RegExp(needle,"g"), "c");
    

    我不建议使用这个原型,它不是很面向对象或标准。。。对于这样一个简单的操作来说,感觉太粗糙了。

        4
  •  1
  •   Juan Pablo Califano    14 年前

    我想不出一个办法来满足你的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);
    

        5
  •  0
  •   www0z0k    14 年前

    "aabbaaba".split('b').join('c') 返回'aaccaaca'

    升级版:

    还有一些在黑名单中没有提到的解决方案(顺便说一句,静态功能比使用prototype-imho要好):

    • 只能使用 replaceAll super() 打电话来。此类的实例将返回 true (myStringInstance is String)
    • 另一个解决方案是:创建一个包装器而不是扩展:一个将为您存储字符串的类,它提供额外的功能(尽管我无法想象一个用于字符串),并可能使其某些属性成为只读的。或者它可能只有一个getter和setter
        6
  •  0
  •   9re    14 年前

    我有两个答案给你。第一个就是你想要的。但我推荐第二个。

    在flex中启用原型非常简单,可以通过设置flex config来完成

    替换所有测试.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);
            }
        }
    }
    

    <?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>
    

    我仍然不鼓励这样做,因为启用原型和关闭严格模式会减慢代码的速度。

        7
  •  0
  •   Dimchao    8 年前

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