Замена регулярных выражений в сервисе vertx - PullRequest
0 голосов
/ 14 мая 2018

Я хотел бы сделать некоторую замену регулярного выражения в службе vertx, где заменяемый текст запрашивается из базы данных. В моем случае я хочу заменить все URL в тексте на более короткие версии этого URL.

Как-то так: (я знаю, это не работает)

public String replaceUrls(String text){
  String urlValidationRegex = "((https?|ftp)://)?(www\\d?|[a-zA-Z0- 9]+)?.[a-zA-Z0-9-]+(\\:|.)([a-zA-Z0-9.]+|(\\d+)?)([/?:].*)?";
  Pattern p = Pattern.compile(urlValidationRegex);
  Matcher m = p.matcher(text);
  StringBuffer sb = new StringBuffer();
  while(m.find()){
    String found = m.group(0); 
    //make async database call
    String shortUrl = urlShortenerService.rxGetShortUrl(found);
    m.appendReplacement(sb, shortUrl); 
  }
  m.appendTail(sb);
  return sb.toString();
}

Я не знаю, как я могу объединить вызов базы данных реактивов с заменой строк регулярного выражения.

Может ли кто-нибудь указать мне правильное направление, как это осуществить?

Спасибо!

1 Ответ

0 голосов
/ 23 мая 2018

Я решил это, реализовав объект-оболочку вокруг него:

public UrlShortenerService replaceUrls(String input, String messageId, String type,  Handler<AsyncResult<String>> resultHandler) {

    Text text = new Text(input);

    Observable
        .fromIterable(text.getOriginalUrlsDistinct()::iterator)
        .flatMap(
            longUrl -> {
                return mongoUrlService
                    .rxFindOrCreateSet(longUrl)
                    .toObservable();
            }
        )
        .flatMap(
            sets -> {
                Map.Entry entry = sets.iterator().next();
                text.addProcessedUrl(entry.getKey().toString(), buildShortUrl(entry.getValue().toString(), messageId, type));
                return Observable.just(true);
            }
        )
        .toList()
        .subscribe(
            allCompleted -> {
                String completeText = text.replaceAll();
                resultHandler.handle(Future.succeededFuture(completeText));
            },
            throwable -> {
                throwable.printStackTrace();
                resultHandler.handle(Future.failedFuture(throwable));
            }
        );

    return this;
}

Класс оболочки (называемый Текст):

public class Text {

    private static final Logger LOGGER = LoggerFactory.getLogger(Text.class);

    private String inputText;
    private HashMap<String, String> processedUrls;
    private Matcher matcher;
    private List<String> originalUrls;

    public Text(String text){
        this.inputText = text;
        String pattern = "(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
        this.matcher = Pattern.compile(pattern).matcher(text);
        originalUrls = new ArrayList<>();
        processedUrls = new HashMap<>();
        findAllUrls();
    }

    public void addOriginalUrl(String url){
        originalUrls.add(url);
    }

    public List<String> getOriginalUrls(){
        return originalUrls;
    }

    public ArrayList<String> getOriginalUrlsDistinct(){
        return new ArrayList(new HashSet(originalUrls));
    }

    public void addProcessedUrl(String originalUrl, String processedUrl){
        processedUrls.put(originalUrl, processedUrl);
    }

    public String replaceAll(){
        String result = "";
        String text = inputText;

        for(HashMap.Entry<String, String> val : processedUrls.entrySet())
        {
            text = text.replace(val.getKey(), val.getValue());
        }

        return text;
    }

    private void findAllUrls(){
        while (matcher.find()){
            String url = matcher.group();
            addOriginalUrl(url);
        }
    }
}

У кого-нибудь есть лучшее решение?

...