Использование функций или методов в Java String.replaceAll () regex - PullRequest
5 голосов
/ 20 января 2011

Я пытаюсь преобразовать 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 ]

13 голосов
/ 20 января 2011

Нет, по крайней мере, не так, как вы делаете это в 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();
}
3 голосов
/ 18 декабря 2012

У меня есть идея о замене пользовательских строк в 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();
        }
    }

<pre> package org.eve.test;</p> <pre><code>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)); } }

Просто для удовольствия.

1 голос
/ 20 января 2011

К сожалению, то, что вы пытаетесь здесь, не сработает. Java использует аппликативную оценку порядка, что означает, что аргументы оцениваются до того, как функция когда-либо будет вызвана. В вашем случае вы получаете длину двухсимвольной строки "$1", а не количество цифр, которые будут записаны в группе № 1.

Итак, когда вы используете эту строку:

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

Что видит функция:

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

Что касается решения вашей проблемы, ответ, опубликованный finnw, будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...