使用Java String.replaceAll()regex中的函数或方法

时间:2011-01-20 00:06:05

标签: java regex string

我正在尝试将RPN方程转换为匹配tigcc规则的字符串。数字必须包含前面的字符数和正面或负面的标记。对于“2”,它将是“1 2 POSINT_TAG”

我对rpn转换器的完整输入是基于正则表达式,所以我想再次使用它们并具有String.replaceAll()函数,如:

string.replaceAll("(\d+)","$1".length+" $1 POSINT_TAG");

但它只是打印:“2号INT_TAG”。我发现了一些类,如com.stevesoft.pat(link)。

在普通的Sun Java中是否有另一种方法可以在替换正则规则的规则中使用(自定义)函数?

3 个答案:

答案 0 :(得分:13)

不,至少与在C#或Ruby中使用它的方式不同。

最接近的是写一个这样的循环:

static Pattern pattern = Pattern.compile("\\d+");
String convert(String input) {
    StringBuffer output = new StringBuffer();
    Matcher matcher = pattern.matcher(input);
    while (matcher.find()) {
        String rep =
            String.format("%d %s POSINT_TAG",
                          matcher.group().length(),
                          matcher.group());
        matcher.appendReplacement(output, rep);
    }
    matcher.appendTail(output);
    return output.toString();
}

答案 1 :(得分:3)

我对Java中的自定义字符串替换有所了解。不像JavaScript中的替换功能那么容易,但它只是工作正常。这是代码:


    package org.eve.util;

    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class StringUtils{
        public static String replaceWithFn(CharSequence input,String regexp,Method fn,int group){
            Matcher m=Pattern.compile(regexp).matcher(input);
            StringBuffer sb=new StringBuffer();
            try {
                Object obj=Modifier.toString(fn.getModifiers()).indexOf("static")>-1?
                        fn.getClass():fn.getDeclaringClass().newInstance();
                if(fn.getReturnType()!=String.class){
                    System.out.println("replacement function must return type \"String\".");
                }
                while(m.find()){
                    m.appendReplacement(sb, (String)fn.invoke(obj, m.group(group)));
                }
                m.appendTail(sb);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    }

    package org.eve.test;

import org.eve.util.StringUtils;

public class ReplaceTest {
    public static void main(String[] args) {
        try {
            StringBuffer input=new StringBuffer("\\u039D\\u03B9\\u03BA\\u03CC\\u03BB\\u03B1\\u03BF\\u03C2 Nicholas \\u5C3C\\u53E4\\u62C9\\u65AF");
            System.out.println("input="+input);
            String result=StringUtils.replaceWithFn(
                input,
                "\\\\u([0-9a-zA-Z]{4})",
                ReplaceTest.class.getMethod("hex2char",String.class),
                1
            );
            System.out.println("output="+result);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public String hex2char(String s){
        //TODO replaceholder
        return String.valueOf((char)Integer.parseInt(s,16));
    }
}

import org.eve.util.StringUtils; public class ReplaceTest { public static void main(String[] args) { try { StringBuffer input=new StringBuffer("\\u039D\\u03B9\\u03BA\\u03CC\\u03BB\\u03B1\\u03BF\\u03C2 Nicholas \\u5C3C\\u53E4\\u62C9\\u65AF"); System.out.println("input="+input); String result=StringUtils.replaceWithFn( input, "\\\\u([0-9a-zA-Z]{4})", ReplaceTest.class.getMethod("hex2char",String.class), 1 ); System.out.println("output="+result); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } public String hex2char(String s){ //TODO replaceholder return String.valueOf((char)Integer.parseInt(s,16)); } }

纯娱乐。

答案 2 :(得分:1)

不幸的是,你在这里尝试的不会起作用。 Java使用应用程序顺序评估,这意味着在调用函数之前评估参数。在您的情况下,您将获得两个字符的字符串"$1"的长度,而不是将在组#1中捕获的位数。

所以当你使用这一行时:

string.replaceAll("(\\d+)","$1".length+" $1 POSINT_TAG");   

该功能看到的是:

string.replaceAll("(\\d+)","2 $1 POSINT_TAG");  

至于你的问题的解决方案,finnw发布的答案将有效。