`

[转]使用正则表达式解决配置文件字符串替换的思路和例子

阅读更多
http://zengrong.net/post/1233.htm

正则表达式是非常强大的字符串处理工具,但由于晦涩难懂,唯有不断的学习和使用,才能积累经验。我使用正则表达式总是断断续续,所以水平也很初级。下面就记录这次的使用经验,备查。

下面的xml代码是一个游戏技能配置文件的简化版,其中的items是一个技能,item是该技能的一个级别的值。desc属性是该技能的介绍文本。由于介绍中包含对技能的效果的引用,而技能的效果在不同的技能级别中的值是不同的,因此这里使用定界符来标识可能会变动的值。

针对定界符,我制定的规则很简单,用花括号{}包含要替换的属性值即可,如{key},其中key就是属性名称。对于使用数组方式提供的属性值,则使用{key[n]}的方式来提供,其中n是数组的索引。

程序中要做的,就是在游戏中需要技能的介绍的时候,会根据技能的级别获取到相关的的值,然后查询desc中有哪些定界符,再根据定界符获取到item中的值,最后进行替换。

这个工作虽然并不复杂,但也不是indexof能够解决的,后面就是我使用正则表达式的处理思路。对于XML的解析,我使用E4X。
<skill>
        <items id="2121" name="魔能烧烬" targetSide="2" type="special1" element="2" desc="主动技能。使魔导师能够掌握魔法精密之处,从而对目标造成{effect[0]}点的火元素伤害,同时减少目标{effect[1]}%MP上限。">
                <item lv="1" effect="[20,4]" targetNum="1" expended="600" cd="20000" />
                <item lv="2" effect="[40,6]" targetNum="1" expended="640" cd="20000" />
        </items>
        <items id="1203" name="无情杀戮" targetSide="2" type="phy" element="-1"  desc="主动技能。没有一丝怜悯的连续两次猛击目标要害,对目标造成{effect}点的物理伤害。">
                <item lv="1" effect="1114" targetNum="1" expended="50" cd="13000" />
                <item lv="2" effect="1180" targetNum="1" expended="60" cd="13000" />
        </items>
</skill>

复制代码
一、检测值是否是数组形式
在这里,由于值都是整数,出现的也值可能是整数数组,所以正则表达式写起来就简单许多:
public static function isArray($str:String):Boolean 
{ 
        $str = $str.replace(/\s/g, ''); 
        var _reg:RegExp = /^\[(\d+,?)+\d+\]$/; 
        return _reg.test($str); 
} 

先使用replace将字符串中的空格剔除,然后检测如[int,int...]的格式。这个正则原理如下:
(\d+,?)+匹配以逗号分隔的整型字符串,例如“123,456”或者“1”这样的格式
第二个\d+则确保“123,”这样的字符串不被匹配
其他的就很简单,不说了


二、将字符串转成数组
先剔除空格,再剔除方括号,然后通过定界符将字符串转成数组,并转换成int存储。其中重点是字符类“[]”的运用。由于要查找的正好是方括号,而正则表达式中也是用方括号来定义字符类的,因此方括号在字符类中,必须使用转义符“\”进行转义才能使用。

public static function toArray($str:String, $delimiter:String=','):Array
{
        $str = $str.replace(/\s/g, '');
        $str = $str.replace(/[\[\]]/g, '');
        var __arr:Array = $str.split($delimiter); 
        for(var i:int=0; i<__arr.length; i++)
                __arr[i] = int(__arr[i]);
        return __arr;
}


三、将XML中的其他值存入一个对象
为了方便后面提取值,将XML中的所有属性存入一个对象中,这里为了演示方便,只存储了effect属性:
public function getSkillVO($id:String, $lv:String):Object
{
        var __itemxml:XML = _skill.items.(@id==$id).item.(@lv==$lv)[0];
        var __vo:Object = {};
        var __effect:String = __itemxml.@effect.toString();
        if(isArray(__effect))
                __vo.effect = toArray(__effect);
        else
                __vo.effect = int(__effect);
        return __vo;
}


四、替换
重要的是String的match方法的作用。这个方法对没有使用global标志“/g”的正则表达式,会将其中的每个组的匹配结果作为一个元素加入到匹配结果数组中。这样,就可以方便的提取到形如{effect[0]}的字符串中的数组索引值。

所有的分析都写在注释中了:
//检测字符串中是否有如{delimter}和{delimter[n]}形式的定界符,并使用对应的值进行替换
private function replaceDesc($str:String, $skillvo:Object):String
{
        //支持全局匹配的正则
        var __globalReg:RegExp = /{(\w+)(\[(\d)\])?}/g;
        //用于匹配每个全局匹配结果的正则
        var __itemReg:RegExp = /{(\w+)(\[(\d)\])?}/;
        //全局匹配的结果
        var __globalMatch:Array = $str.match(__globalReg);
        //待替换的键名数组
        var __keys:Array = [];
        //待替换的值数组
        var __values:Array = [];

        var __itemMatch:Array = null;
        var __itemIsArray:Boolean = false;
        var __itemKey:String = '';
        for each(var __str:String in __globalMatch)
        {
                __itemMatch = __str.match(__itemReg);
                /*按照正则表达式规则,__itemMatch应该是有4个元素的数组:
                1 整个字符串,2 第一个括号(\w+)的内容,3 第二个括号(\[(\d)\])的内容,4 第三个括号(\d)的内容
                因此,如果第4个元素为undefined,就说明在字符串中,没有数组的定界符*/
                __itemIsArray =  __itemMatch[3] != undefined;
                //第2个元素就是去掉了花括号和数组定界符(如果有)的字符串,也就是要$skillvo中的变量名
                __itemKey = __itemMatch[1];
                //第1个元素是整个大字符串中的要被替换的部分,包含花括号
                __keys.push(__itemMatch[0]);
                //如果值是数组中的元素,就是用数组中对应索引的值
                if(__itemIsArray)
                        __values.push($skillvo[__itemKey][__itemMatch[3]]);
                //否则,就直接使用变量的值
                else
                        __values.push($skillvo[__itemKey]);
        }
        //开始替换
        for(var j:int=0; j<__keys.length; j++)
        {
                $str = $str.replace(__keys[j], __values[j]);
        }
        return $str;
}

分享到:
评论

相关推荐

    qt使用正则表达式限制lineEdit的输入,对正则表达式进行了封装,可以直接引入,工程编译正常

    在Qt框架中,正则表达式(Regular Expression)是一种强大的文本处理工具,它允许程序员以结构化的方式匹配、查找、替换或验证字符串。本项目针对Qt的lineEdit组件,通过正则表达式实现了输入限制功能,使得lineEdit...

    python正则表达式例子

    正则表达式是一种强大的文本处理工具,能够帮助我们高效地完成字符串的查找、替换等操作。下面将结合具体的例子来详细介绍正则表达式的使用方法及其应用场景。 ### 1. 分析表空间使用率 在第一个例子中,我们需要...

    正则表达式处理html文本例子

    1. **基本正则表达式概念**:正则表达式是由字符和特殊符号组成的字符串,它们定义了一个模式,用于匹配一系列的字符串。例如,`\d`代表任何数字,`.`代表任意字符,`*`表示前面的元素可以重复零次或多次。 2. **...

    正则表达式测试工具

    正则表达式(Regular Expression,简称Regex)是一种强大的文本处理工具,用于匹配、查找、替换或提取字符串中的模式。在编程领域,正则表达式被广泛应用于数据验证、文本搜索和处理等方面。为了方便开发者测试和...

    8 正则表达式1

    正则表达式(Regular Expression,简称regex)是编程和数据处理中的强大工具,它通过一套特定的字符和语法来描述字符串的模式,用于文本的搜索、匹配、分割、替换等多种功能。在Linux操作系统中,正则表达式尤其常见...

    ibatis例子加教程&java&javascript&dhtml&正则表达式工具

    标题中的“ibatis例子加教程&java&javascript&dhtml&正则表达式工具”涵盖了五个主要的IT技术领域:iBATIS、Java、JavaScript、DHTML和正则表达式。接下来,我们将深入探讨这些技术及其相关的知识点。 1. iBATIS: ...

    Winform做的正则表达式替换助手

    6. **保存和加载配置**:用户可能希望保存他们的正则表达式和替换规则以备后用,所以应用可以提供保存和加载配置的选项,这涉及到文件操作,如读写XML或JSON文件。 在实现以上功能时,还需要注意错误处理,比如确保...

    SQL 正则表达式及mybatis中使用正则表达式

    正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串。在SQL中,正则表达式常用于复杂的数据过滤和查询。MySQL支持使用`REGEXP`和`NOT REGEXP`(或者`RLIKE`和`NOT RLIKE`)操作符来进行正则...

    正则表达式校检器源码

    正则表达式是一种强大的文本处理工具,用于在字符串中匹配、查找、替换或者提取符合特定模式的文本。在编程中,正则表达式被广泛应用于数据验证、文本搜索与替换等场景。"正则表达式校检器源码"是一个专门为开发者...

    vc++6.0环境下的使用boost库实现正则表达式

    下面将详细讲解如何在VC++ 6.0环境中配置和使用Boost库来实现正则表达式功能。 首先,我们需要下载Boost库。你可以从官方网站http://www.boost.org/ 下载源码包。选择最新稳定的版本,例如`boost_1_74_0.zip`。下载...

    Python使用正则表达式分割字符串的实现方法

    使用正则表达式分割字符串是处理文本数据时常用的技术之一,尤其是在处理日志文件、配置文件或从HTML/XML中提取数据时。掌握正则表达式不仅可以提高开发效率,还能让代码更加简洁、易于维护。 最后,要注意的是,...

    正则表达式收集

    这篇博客"正则表达式收集"可能是一个关于正则表达式使用的综合资源集合,尽管描述部分为空,但我们可以从标签"源码"和"工具"推测,该资源可能包含了一些实际的代码示例和实用工具,以帮助用户更好地理解和运用正则...

    ruby 正则表达式详解及示例代码

    在Ruby中,正则表达式被广泛应用于文本处理、数据验证、文件操作等多个场景,尤其是在使用Ruby编写的Puppet配置文件(即pp文件)中,正则表达式的使用尤为频繁。 在Ruby中,正则表达式可以使用斜杠(/)界定,也...

    前端开源库-regx

    3. `README.md`:项目的说明文件,包含了如何安装、使用和配置`regx`的详细信息。 4. `LICENSE`:项目的许可协议,说明了使用该库的法律条款。 5. `package.json`:定义了项目的元数据,包括依赖、版本、作者等信息...

    前端开源库-to-regexp

    在前端开发中,正则表达式(Regular Expression,简称RegExp)是处理文本的强大工具,能够进行复杂的模式匹配和替换操作。然而,对于非专业人士来说,直接编写正则表达式可能会非常困难。`to-regexp`是一个前端开源...

    CSV文件上传下载分隔符问题以及ABAP正则式

    此外,如果需要更灵活地处理数据格式,可以使用ABAP的字符串操作函数,如`REPLACE`或`REGEX_REPLACE`,它们可以处理复杂的分隔符替换需求。 正则表达式在处理CSV分隔符问题时非常有用。ABAP从7.40版本开始支持正则...

    由正则批量修改文件-易语言

    通过XML文件,用户可以清晰地定义替换规则,包括要查找的正则表达式和替换后的字符串。例如,以下是一个简单的XML规则示例: ```xml &lt;search&gt;old_pattern &lt;replace&gt;new_pattern ``` 在这个例子中,`old_...

    BAT批处理脚本-文本操作-去掉字符串不同部位的空格.cmd.zip

    `则是使用字符串替换功能来移除空格。`!str: =!`将所有连续的空格替换为空,而`!str:\s+=!`则匹配并移除所有单个的空格(这里的`\s`是正则表达式中的空白字符匹配)。 这个批处理脚本可以应用于大量文本数据的...

    editplus 代码编辑器html c++ jsp css

    选中“正则表达式”复选框,表明我们要在查找、替换中使用正则表达式。然后,选中“替换范围”中的“当前文件”,表明对当前文件操作。 ②、单击“查找内容”组合框右侧的按钮,出现下拉菜单。 ③、下面的操作添加...

    libboost_regex.zip

    它提供了一个强大且灵活的接口,使得开发者能够方便地进行字符串匹配、搜索、替换等一系列正则表达式相关的操作。这个库在Windows平台上的应用,通常需要与特定的编译器版本相匹配。在给定的压缩包文件"libboost_...

Global site tag (gtag.js) - Google Analytics