有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

vertx服务中java正则表达式的替换

我想在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();
}

我不知道如何将reactivex数据库调用与regex字符串替换结合起来

有人能给我指出正确的方向吗

谢谢!


共 (1) 个答案

  1. # 1 楼答案

    我通过在其周围实现一个包装器对象来解决这个问题:

    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;
    }
    

    包装器类(称为Text):

    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);
            }
        }
    }
    

    有谁有更好的解决方案吗