如何从Java中的应用程序中提取所有字符串

时间:2011-10-05 15:48:45

标签: java regex string

在Android应用程序中,所有字符串值都是硬编码的(标签,对话框标题,按钮等)。我的任务是将所有这些字符串提取到资源文件中。 没有手动浏览代码并制作大量的c / p,有没有办法从应用程序中提取所有字符串?使用正则表达式?我正在考虑编写一个类似于“。*”的模式。  或者以某种方式解析代码?

编辑:我知道Eclipse的externalize字符串,但是它创建了.properties文件,我需要的是.xml文件。因此,需要再次努力将其转换为.xml文件。

我正在考虑编写一个简单的程序,它将使用找到的类的名称提取所有字符串。

2 个答案:

答案 0 :(得分:3)

Eclipse提供了externalize strings向导。对于特定于Android的解决方案:Externalize strings for Android project

希望它有所帮助。

答案 1 :(得分:1)

我写了一个简短的程序来帮助我实现这个目标。我有一个包含超过一百个字符串的文件,所以只需按Ctrl + 1 - >输入每一行都会有太多麻烦。

小程序将.java文件的文件位置作为输入,并将信息放入C& P的控制台。一个人可以想象一下改进它来爬行文件系统并为所有.java文件做这件事,但这对我来说已经足够了......

package de.panschk.androidutil;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;

public class ExtractStringHelper {

public static void main (String[] args) throws IOException {
    String fileName = "LOCATION OF .JAVA FILE";
    FileInputStream fis = new FileInputStream(fileName);
    streamToStringReplaceEntities(fis);
    fis.close();

}

private static Set<String> varNames= new HashSet<String>();
public static void streamToStringReplaceEntities(InputStream is)
        throws IOException {
    BufferedInputStream bis = new BufferedInputStream(is);
    ByteArrayOutputStream codeOut = new ByteArrayOutputStream();
    StringBuffer xmlOut = new StringBuffer();
    boolean inLineComment = false;
    boolean inMultilineComment = false;
    boolean inQuotes = false;
    char lastChar = ' ';
    ByteArrayOutputStream stringContent = new ByteArrayOutputStream();
    int result = bis.read();
    while (result != -1) {
        boolean inComment = inLineComment || inMultilineComment;
        byte b = (byte) result;
        // read next byte
        result = bis.read();
        boolean copyCharToBuffer = true;
        if (!inQuotes && !inComment && b == '"') {
            stringContent = new ByteArrayOutputStream();
            inQuotes = true;
            copyCharToBuffer = false;
        } else if (inQuotes && b == '"') {
            String content = stringContent.toString("UTF-8");
            String varName = makeVariableName(content);
            inQuotes = false;
            addXMLContent(varName, content, xmlOut);
            addCodeContent(varName, codeOut);
            copyCharToBuffer = false;

        } else if (inQuotes) {
            copyCharToBuffer = false;
            stringContent.write(b);

        } else if (!inComment && !inQuotes && lastChar == '/' && b == '/') {
            inLineComment = true;
        } else if (!inComment && !inQuotes && lastChar == '/' && b == '*') {
            inMultilineComment = true;
        } else if (inLineComment && b == '\n') {
            inLineComment = false;
        } else if (inMultilineComment && lastChar == '*' && b == '/') {
            inMultilineComment = false;
        }

        if (copyCharToBuffer) {
            codeOut.write(b);
        }
        lastChar = (char) b;
    }

    System.out.println(codeOut.toString("UTF-8"));
    System.out.println(xmlOut.toString());

}

private static void addCodeContent(String varName,
        ByteArrayOutputStream codeOut) throws IOException {
    String contentToAdd = "getResources().getString(R.string."+varName+")";
    byte[] bytes;
    try {
        bytes = contentToAdd.getBytes("UTF-8");
        codeOut.write(bytes);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

}

private static void addXMLContent(String varName, String content,
        StringBuffer xmlOut) {
    if (!varNames.contains(varName)) {
        content = content.replace("'", "\\'");
        xmlOut.append("    <string name=\"").append(varName).append("\">").append(content).append("</string>\n");
        varNames.add(varName);
    }

}

static String makeVariableName(String s) {
    s = s.replace(' ', '_');
    s = s.replaceAll("[^A-Za-z0-9_]", "").toLowerCase();
    return s;
}

}