我正在尝试将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中是否有另一种方法可以在替换正则规则的规则中使用(自定义)函数?
答案 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发布的答案将有效。