Как создать регулярное выражение статьи на Java? - PullRequest
1 голос
/ 03 августа 2010

Скажем, например, я хочу взять эту фразу:

{{Hello | What Up | Howdy} {world | planet} |{Goodbye | Later} {люди | граждане | жители}}

и случайным образом превращают его в одно из следующего:

Hello world
Goodbye people
What's Up word
What's Up planet
Later citizens
etc.

Основная идея заключается в том, что заключено в каждую паруфигурных скобок будет неограниченное количество вариантов, разделенных "|".Программа должна пройти и случайным образом выбрать один вариант для каждого набора скобок.Имейте в виду, что фигурные скобки могут бесконечно вкладываться друг в друга.Я нашел ветку об этом и попытался преобразовать ее в Java, но это не сработало.Вот код Python, который предположительно работал:

import re
from random import randint

def select(m):
    choices = m.group(1).split('|')
    return choices[randint(0, len(choices)-1)]

def spinner(s):
    r = re.compile('{([^{}]*)}')
    while True:
        s, n = r.subn(select, s)
        if n == 0: break
    return s.strip()

Вот моя попытка преобразовать этот код Python в Java.

public String generateSpun(String text){
    String spun = new String(text);
    Pattern reg = Pattern.compile("{([^{}]*)}");
    Matcher matcher = reg.matcher(spun);
    while (matcher.find()){
       spun = matcher.replaceFirst(select(matcher.group()));
    }
    return spun;
}

private String select(String m){
    String[] choices = m.split("|");
    Random random = new Random();
    int index = random.nextInt(choices.length - 1);
    return choices[index];
}

К сожалению, когда я пытаюсь проверить это, вызвав

generateAd("{{Hello|What's Up|Howdy} {world|planet} | {Goodbye|Later} {people|citizens|inhabitants}}");

В основной части моей программы она выдает ошибку в строке в generateSpun, где объявляется Pattern reg, и дает мне PatternSyntaxException.

java.util.regex.PatternSyntaxException: Illegal repetition
{([^{}]*)}

Может кто-то попытаться создатьметод Java, который будет делать то, что я пытаюсь сделать?

Ответы [ 4 ]

1 голос
/ 03 августа 2010

Вот некоторые проблемы с вашим текущим кодом:

  • Вы должны повторно использовать ваш скомпилированный Pattern вместо Pattern.compile каждый раз
  • Вы должны повторно использовать свой Random вместо new Random каждый раз
  • Имейте в виду, что String.split основано на регулярных выражениях, поэтому вы должны split("\\|")
  • Имейте в виду, что фигурные скобки в регулярном выражении Java должны быть экранированы для буквального соответствия, поэтому Pattern.compile("\\{([^{}]*)\\}");
  • Вы должны запросить group(1), а не group(), по умолчанию для группы 0
  • Вы используете replaceFirst неправильно, ищите Matcher.appendReplacement/Tail вместо
  • Random.nextInt(int n) имеет исключительную верхнюю границу (как и многие другие методы в Java)
  • Сам алгоритм фактически не обрабатывает произвольно вложенные скобки должным образом

Обратите внимание, чтоэкранирование выполняется с помощью \, и в качестве строкового литерала Java его необходимо удвоить (т. е. "\\" содержит один символ, обратную косую черту).

Attachment

0 голосов
/ 22 апреля 2017

Используйте это, будет работать ... Я сделал, и отлично работает

Pattern p = Pattern.compile("cat");
 Matcher m = p.matcher("one cat two cats in the yard");
 StringBuffer sb = new StringBuffer();
 while (m.find()) {
     m.appendReplacement(sb, "dog");
 }
 m.appendTail(sb);
 System.out.println(sb.toString());

и здесь

private String select(String m){
    String[] choices = m.split("|");
    Random random = new Random();
    int index = random.nextInt(choices.length - 1);
    return choices[index];
}

m.split("|") использовать m.split("\\|")

В противном случае он разделяет каждый символ

и использует Pattern.compile("\\{([^{}]*)\\}");

0 голосов
/ 25 апреля 2016

Ну, я только что создал один на PHP & Python, демонстрация здесь http://spin.developerscrib.com, это на очень ранней стадии, поэтому может не сработать, исходный код на github: https://github.com/razzbee/razzy-spinner

0 голосов
/ 03 августа 2010

Чтобы исправить регулярное выражение, добавьте обратную косую черту перед внешними { и }.Это метасимволы в регулярных выражениях Java.Однако я не думаю, что это приведет к рабочей программе.Вы модифицируете переменную spun после ее привязки к регулярному выражению, и я не думаю, что возвращаемый Matcher будет отражать обновленное значение.

Я также не думаю, что код python будет работать для вложенныхвыбор.Вы на самом деле пробовали код Python?Вы говорите, что он «предположительно работает», но было бы разумно проверить это, прежде чем тратить много времени на его перенос на Java.

...