Flash、Ant以及大量正则表达式替换

发布于 2024-12-11 17:41:23 字数 1393 浏览 0 评论 0原文

我有一个 Flash 项目,出于优化目的,必须在发布构建期间将常量引用替换为文字。

我想要替换数百个常量。所有这些都以这种格式存储在单个文件中:

FILE: Constants.as
public static const CONST_1         :uint = 0;
public static const CONST_LOLO      :int = -1;
public static const CONST_WHEE      :Number = 2.55;
public static const OTHER_CONST     :String = "La string!";
public static const ITSAMEMARIO     :String = "O, HAI!";
public static const MAGE_WALL       :uint = 15;

我想我可以手动完成,就像这样:

<replaceregexp match="CONST_1" replace="0">
    <fileset dir="${project.sourcePath}" includes="**/*.as" />
</replaceregexp>
<replaceregexp match="CONST_LOLO" replace="-1">
    <fileset dir="${project.sourcePath}" includes="**/*.as" />
</replaceregexp>

对于所有其他变量,依此类推。问题是双重的——首先,工作量相当大。但更大的问题是,这些常量可以改变,我必须记住在两个地方进行改变。

一般来说,我使用 Ant(我也刚刚开始学习)来完成这个任务,但如果你认为有更好的方法,我洗耳恭听。我能想到两种解决方案,但我都不知道如何执行:

  1. 编写一些自作聪明的 Ant 代码,它会解析这个常量文件,并愉快地进行替换,将所有内容保留在内存中。
  2. 让任务首先解析Constants.as,输出一个新的Ant脚本,然后由第一个任务执行。

我使用 Flash Builder 4.5 来满足我所有的 Ant 需求。

编辑: 一些澄清。在项目中我使用常量,例如LEVEL_WIDTH。所有这些常量都在前面提到的 Constants.as 中声明。现在我想要的是将整个项目中这些常量的所有实例替换为它们的实际值。所以这样的行:

return (x >= 0 && x < Constants.LEVEL_WIDTH);

将被替换为:

return (x >= 0 && x < 20);

I have a flash project which, for optimization purposes, has to have constant references replaced with literals during release build.

There are hundreds of constants which I want to replace. All of them are stored in single file, in this format:

FILE: Constants.as
public static const CONST_1         :uint = 0;
public static const CONST_LOLO      :int = -1;
public static const CONST_WHEE      :Number = 2.55;
public static const OTHER_CONST     :String = "La string!";
public static const ITSAMEMARIO     :String = "O, HAI!";
public static const MAGE_WALL       :uint = 15;

I figure I could do it manually, like that:

<replaceregexp match="CONST_1" replace="0">
    <fileset dir="${project.sourcePath}" includes="**/*.as" />
</replaceregexp>
<replaceregexp match="CONST_LOLO" replace="-1">
    <fileset dir="${project.sourcePath}" includes="**/*.as" />
</replaceregexp>

And so on, for all the other variables. The problem is twofold - first of all, it is quite a lot of work. But the bigger problem is, that these constants can change and I'd have to remember to do the change in two places.

Generally I am using Ant (which I just started to learn too) to accomplish this task, but if you think there is a better way, I am all ears. There are two solutions I can think of, none of which I know how to execute:

  1. Write some smarty-pants piece of Ant code which would parse this constants file and happily do the replaces keeping everything in memory.
  2. Make the task first parse the Constants.as, output a new Ant script, which then will be executed by the first task.

I am using Flash Builder 4.5 for all my Ant needs.

EDIT:
Some clarification. In the project I am using Constants, for example LEVEL_WIDTH. All of these constants are declared in the aforementioned Constants.as. Now what I want is to replace all of the instances of these constants in the whole project with their actual value. So such line:

return (x >= 0 && x < Constants.LEVEL_WIDTH);

will be replaced by:

return (x >= 0 && x < 20);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我早已燃尽 2024-12-18 17:41:23

好吧,这不是使用 ant 做的最简单的事情。首先你需要知道你可以改变什么。这意味着常量的所有名称以及相应的值。常量名称是否唯一?如果是的话,这对我来说听起来像是一个地图结构。然后,您需要 regexreplace 包含一个或多个这些变量的所有源文件,以便每个常量都替换为实际值。这不是 ant 的设计目的,但您可以使用脚本 def 来做到这一点。

我会像这样使用 java 来做到这一点:

将所有常量/值存储到映射中(如果常量是唯一的),否则使用不同的结构。

示例代码:

<project name="test" default="build">
  <property name="constants" value="constants.txt"/>

  <scriptdef name="replaceConstants" language="java">
    <attribute name="constants" />
    <attribute name="srcFile" />
    <![CDATA[
      import java.util.*;
      import java.util.regex.*;
      ArrayList constantNameList = new ArrayList();
      ArrayList constantValueList = new ArrayList();

      var constantFile = attributes.get("constants");
      Pattern regex = Pattern.compile("(?<=const)\\s+(\\b\\w+\\b).*?=\\s*(.*?)\\s*;");
        Matcher regexMatcher = regex.matcher(constantFile);
        while (regexMatcher.find()) {
            constantNameList.add(regexMatcher.group(1));
        constantValueList.add(regexMatcher.group(2));
        }
      for(int i = 0; i < constantNameList.size(); ++i)
      {
        //debugging
        System.out.print("key : ");
        System.out.print(constantNameList.get(i));
        System.out.print(" value : ");
        System.out.println(constantValueList.get(i));
        //do the actual replacement here
      }
     ]]>
  </scriptdef>

  <target name="build">
    <loadfile property="constants.file" srcFile="${constants}"/>
    <loadfile property="source.file" srcFile="sourceFile.txt"/>
    <echo message="${constants.file}"/>
    <replaceConstants constants="${constants.file}" srcFile="${source.file}"/>
  </target>
</project>

您需要 java 1.6 或更高版本才能运行它以及 http://www.java2s.com/Code/Jar/ABC/bsh-2.0b5.jar.htm

这个jar来运行它。

输出:

[replaceConstants] key : CONST_1 value : 0
[replaceConstants] key : CONST_LOLO value : -1
[replaceConstants] key : CONST_WHEE value : 2.55
[replaceConstants] key : OTHER_CONST value : "La string!"
[replaceConstants] key : ITSAMEMARIO value : "O, HAI!"
[replaceConstants] key : MAGE_WALL value : 15

所以我所做的是将所有常量名称/值存储到两个数组中。您需要迭代每个源文件的数组和正则表达式替换。整个事情可以是一个可以多次调用的宏定义。

OK this is not the easiest thing to do with ant. First you need to know what you can change. This means all the names of your constants as well as the corresponding values. Are the constant names unique? If yes this sounds like a map structure to me. Then you need to regexreplace all your source files which contain one or more of these variables so that every constant is replaced with the actual value. This is not what ant is designed for but you can do it with a script def.

I would do this with java like this :

Store all constant/values into a map (if the constants are unique) else use a different structure.

Sample code :

<project name="test" default="build">
  <property name="constants" value="constants.txt"/>

  <scriptdef name="replaceConstants" language="java">
    <attribute name="constants" />
    <attribute name="srcFile" />
    <![CDATA[
      import java.util.*;
      import java.util.regex.*;
      ArrayList constantNameList = new ArrayList();
      ArrayList constantValueList = new ArrayList();

      var constantFile = attributes.get("constants");
      Pattern regex = Pattern.compile("(?<=const)\\s+(\\b\\w+\\b).*?=\\s*(.*?)\\s*;");
        Matcher regexMatcher = regex.matcher(constantFile);
        while (regexMatcher.find()) {
            constantNameList.add(regexMatcher.group(1));
        constantValueList.add(regexMatcher.group(2));
        }
      for(int i = 0; i < constantNameList.size(); ++i)
      {
        //debugging
        System.out.print("key : ");
        System.out.print(constantNameList.get(i));
        System.out.print(" value : ");
        System.out.println(constantValueList.get(i));
        //do the actual replacement here
      }
     ]]>
  </scriptdef>

  <target name="build">
    <loadfile property="constants.file" srcFile="${constants}"/>
    <loadfile property="source.file" srcFile="sourceFile.txt"/>
    <echo message="${constants.file}"/>
    <replaceConstants constants="${constants.file}" srcFile="${source.file}"/>
  </target>
</project>

You will need java 1.6 or later to run this as well as http://www.java2s.com/Code/Jar/ABC/bsh-2.0b5.jar.htm

This jar to run it.

Output :

[replaceConstants] key : CONST_1 value : 0
[replaceConstants] key : CONST_LOLO value : -1
[replaceConstants] key : CONST_WHEE value : 2.55
[replaceConstants] key : OTHER_CONST value : "La string!"
[replaceConstants] key : ITSAMEMARIO value : "O, HAI!"
[replaceConstants] key : MAGE_WALL value : 15

So what I did is stored all the constant names/value into two arrays. You need to iterate through the arrays and regex replace for each of your source files. The whole thing can be a macrodef which you can call multiple times.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文