Как заменить ряд маркеров в Строке Java?

У меня работает следующий код:

df =df.groupby('top_level_domain')['category'].agg([('category', ', '.join)]).reset_index()
106
задан Raman Sahasi 1 August 2016 в 10:16
поделиться

8 ответов

Наиболее эффективным способом было бы использование средства сопоставления для постоянного поиска выражений и их замены, а затем добавления текста в построитель строк:

Pattern pattern = Pattern.compile("\\[(.+?)\\]");
Matcher matcher = pattern.matcher(text);
HashMap<String,String> replacements = new HashMap<String,String>();
//populate the replacements map ...
StringBuilder builder = new StringBuilder();
int i = 0;
while (matcher.find()) {
    String replacement = replacements.get(matcher.group(1));
    builder.append(text.substring(i, matcher.start()));
    if (replacement == null)
        builder.append(matcher.group(0));
    else
        builder.append(replacement);
    i = matcher.end();
}
builder.append(text.substring(i, text.length()));
return builder.toString();
65
ответ дан 24 November 2019 в 03:45
поделиться

Следующие переменные замен формы <<VAR>>, со значениями, искавшими из Карты. Вы можете тест это онлайн здесь

, Например, со следующей входной строкой

BMI=(<<Weight>>/(<<Height>>*<<Height>>)) * 70
Hi there <<Weight>> was here

и следующие значения переменных

Weight, 42
Height, HEIGHT 51

выводы следующим

BMI=(42/(HEIGHT 51*HEIGHT 51)) * 70

Hi there 42 was here

Вот является код

  static Pattern pattern = Pattern.compile("<<([a-z][a-z0-9]*)>>", Pattern.CASE_INSENSITIVE);

  public static String replaceVarsWithValues(String message, Map<String,String> varValues) {
    try {
      StringBuffer newStr = new StringBuffer(message);
      int lenDiff = 0;
      Matcher m = pattern.matcher(message);
      while (m.find()) {
        String fullText = m.group(0);
        String keyName = m.group(1);
        String newValue = varValues.get(keyName)+"";
        String replacementText = newValue;
        newStr = newStr.replace(m.start() - lenDiff, m.end() - lenDiff, replacementText);
        lenDiff += fullText.length() - replacementText.length();
      }
      return newStr.toString();
    } catch (Exception e) {
      return message;
    }
  }


  public static void main(String args[]) throws Exception {
      String testString = "BMI=(<<Weight>>/(<<Height>>*<<Height>>)) * 70\n\nHi there <<Weight>> was here";
      HashMap<String,String> values = new HashMap<>();
      values.put("Weight", "42");
      values.put("Height", "HEIGHT 51");
      System.out.println(replaceVarsWithValues(testString, values));
  }

и хотя не требуемый, можно использовать аналогичный подход для замены переменных в строке со свойствами из application.properties файла:

private static Pattern patternMatchForProperties =
      Pattern.compile("[$][{]([.a-z0-9_]*)[}]", Pattern.CASE_INSENSITIVE);

protected String replaceVarsWithProperties(String message) {
    try {
      StringBuffer newStr = new StringBuffer(message);
      int lenDiff = 0;
      Matcher m = patternMatchForProperties.matcher(message);
      while (m.find()) {
        String fullText = m.group(0);
        String keyName = m.group(1);
        String newValue = System.getProperty(keyName);
        String replacementText = newValue;
        newStr = newStr.replace(m.start() - lenDiff, m.end() - lenDiff, replacementText);
        lenDiff += fullText.length() - replacementText.length();
      }
      return newStr.toString();
    } catch (Exception e) {
      return message;
    }
  }
0
ответ дан 24 November 2019 в 03:45
поделиться

В прошлом я решал эту проблему с помощью StringTemplate и Groovy Templates .

В конечном счете, решение об использовании механизма шаблонов или отказе от него должно основываться на следующих факторах:

  • Будет ли у вас много таких шаблонов в приложении?
  • Вам нужна возможность изменять шаблоны без перезапуска приложение?
  • Кто будет поддерживать эти шаблоны? Программист на Java или бизнес-аналитик, участвующий в проекте?
  • Потребуется ли вам возможность добавлять логику в ваши шаблоны, например, условный текст, основанный на значениях переменных?
  • Потребуется ли вам возможность включать в шаблон другие шаблоны?

Если что-либо из вышеперечисленного применимо к вашему проекту, я бы подумал об использовании механизма шаблонов, большинство из которых предоставляют эту функциональность,

0
ответ дан 24 November 2019 в 03:45
поделиться

Это зависит от где находятся фактические данные, которые вы хотите заменить. У вас может быть такая карта:

Map<String, String> values = new HashMap<String, String>();

, содержащая все данные, которые можно заменить. Затем вы можете перебирать карту и изменять все в строке следующим образом:

String s = "Your String with [Fields]";
for (Map.Entry<String, String> e : values.entrySet()) {
  s = s.replaceAll("\\[" + e.getKey() + "\\]", e.getValue());
}

Вы также можете перебирать строку и находить элементы на карте. Но это немного сложнее, потому что вам нужно проанализировать строку в поисках []. Вы можете сделать это с помощью регулярного выражения, используя Pattern и Matcher.

8
ответ дан 24 November 2019 в 03:45
поделиться

Я действительно не думаю, что вам нужно использовать для этого шаблонизатор или что-то подобное. Вы можете использовать метод String.format , например:

String template = "Hello %s Please find attached %s which is due on %s";

String message = String.format(template, name, invoiceNumber, dueDate);
103
ответ дан 24 November 2019 в 03:45
поделиться

Вы можете попробовать использовать шаблон библиотека, такая как Apache Velocity.

http://velocity.apache.org/

Вот пример:

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.StringWriter;

public class TemplateExample {
    public static void main(String args[]) throws Exception {
        Velocity.init();

        VelocityContext context = new VelocityContext();
        context.put("name", "Mark");
        context.put("invoiceNumber", "42123");
        context.put("dueDate", "June 6, 2009");

        String template = "Hello $name. Please find attached invoice" +
                          " $invoiceNumber which is due on $dueDate.";
        StringWriter writer = new StringWriter();
        Velocity.evaluate(context, writer, "TemplateName", template);

        System.out.println(writer);
    }
}

Результат будет:

Hello Mark. Please find attached invoice 42123 which is due on June 6, 2009.
41
ответ дан 24 November 2019 в 03:45
поделиться

К сожалению удобный метод String .format, упомянутый выше, доступен только начиная с Java 1.5 (который в настоящее время должен быть довольно стандартным, но вы никогда не узнаете). Вместо этого вы также можете использовать Java-класс MessageFormat для замены заполнителей.

Он поддерживает заполнители в форме '{number}', поэтому ваше сообщение будет выглядеть как "Привет {0}, пожалуйста, прикрепите {1}, который подлежит оплате {2} ". Эти строки можно легко перенести во внешний вид с помощью ResourceBundles (например, для локализации с несколькими языковыми стандартами). Замена будет выполнена с использованием статического метода'format 'класса MessageFormat:

String msg = "Hello {0} Please find attached {1} which is due on {2}";
String[] values = {
  "John Doe", "invoice #123", "2009-06-30"
};
System.out.println(MessageFormat.format(msg, values));
42
ответ дан 24 November 2019 в 03:45
поделиться
String.format("Hello %s Please find attached %s which is due on %s", name, invoice, date)
9
ответ дан 24 November 2019 в 03:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: