【问题标题】:How to replace all domains with pattern in a XML string in Java?如何用 Java 中的 XML 字符串中的模式替换所有域?
【发布时间】:2018-02-02 16:31:56
【问题描述】:

我有一个这样的 XML 输出( 元素或 xlink:href 属性只是虚构的,您不能依赖它们来创建正则表达式模式。

<xml>http://localhost:8080/def/abc/xyx</xml>
<element xlink:href="http://localhostABCDEF/def/ABC/XYZ">Some Text</element>
...

我想做的是使用 Java 正则表达式替换域模式(我不知道现有域):

"http(s)?://.*/def/.*

带有输入域(例如:http://google.com/def),结果将是:

<xml>http://google.com/def/abc/xyx</xml>
<element xlink:href="http://google.com.com/def/ABC/XYZ">Some Text</element>
...

我该怎么做?我认为 Java 中的 Regex 可以做或 String.replaceAll (但这似乎不可能)。

【问题讨论】:

  • 我会使用 XML 解析器(如果您的文件很小,则使用 DOM,否则使用事件驱动)并且对于您知道的每个元素都将包含 URL(在您的情况下,显然是 xml),用该元素初始化一个URL 对象,获取URL 对象的path,然后用不同的域再次构造。
  • 在你的正则表达式中使用反向引用 "http(s)?://(.*)/def/.*"
  • 对一个密切相关的问题的史诗般的回答:stackoverflow.com/questions/1732348/…
  • 为什么在你的xml标签路径/def/abc/xyx小写和href大写/def/ABC/XYZ
  • @LuisMuñoz 您没有在发布的内容中添加任何反向引用,您只是复制了原始正则表达式并粘贴了它。我错过了什么吗?

标签: java regex xml parsing url


【解决方案1】:

正则表达式http[s]?:\/{2}.+\/def 替换http://google.com/def

详情

  • ? 匹配 0 次和 1 次
  • [] 匹配列表中存在的单个字符
  • . 匹配任意字符
  • + 匹配一次到无限次

Java 代码

String domain = "http://google.com/def";
String html = "<xml>http://localhost:8080/def/abc/xyx</xml>\r\n<element xlink:href=\"http://localhostABCDEF/def/ABC/XYZ\">Some Text</element>";

html = html.replaceAll("http[s]?:\\/{2}.+\\/def", domain);
System.out.print(html);

输出

<xml>http://google.com/def/abc/xyx</xml>
<element xlink:href="http://google.com/def/ABC/XYZ">Some Text</element>

【讨论】:

  • 感谢您的努力,但 元素或 xlink:href 属性只是虚构的,您不能依赖它们来创建正则表达式模式。它们可能是不同的元素名称、属性,我想要的是替换 XML 字符串中的域名,这似乎 XPath 是可能的。
  • @Bằng Rikimaru 已更新。
【解决方案2】:

实际上,这可以通过正则表达式来完成,而且比解析 XML 文档要简单。答案如下:

String text = "<epsg:CommonMetaData>\n"
            + "      <epsg:type>geographic 2D</epsg:type>\n"
            + "      <epsg:informationSource>EPSG. See 3D CRS for original information source.</epsg:informationSource>\n"
            + "      <epsg:revisionDate>2007-08-27</epsg:revisionDate>\n"
            + "      <epsg:changes>\n"
            + "        <epsg:changeID xlink:href=\"http://www.opengis.net/def/change-request/EPSG/0/2002.151\"/>\n"
            + "        <epsg:changeID xlink:href=\"http://www.opengis.net/def/change-request/EPSG/0/2003.370\"/>\n"
            + "        <epsg:changeID xlink:href=\"http://www.opengis.net/def/change-request/EPSG/0/2006.810\"/>\n"
            + "        <epsg:changeID xlink:href=\"http://www.opengis.net/def/change-request/EPSG/0/2007.079\"/>\n"
            + "      </epsg:changes>\n"
            + "      <epsg:show>true</epsg:show>\n"
            + "      <epsg:isDeprecated>false</epsg:isDeprecated>\n"
            + "    </epsg:CommonMetaData>\n"
            + "  </gml:metaDataProperty>\n"
            + "  <gml:metaDataProperty>\n"
            + "    <epsg:CRSMetaData>\n"
            + "      <epsg:projectionConversion xlink:href=\"http://www.opengis.net/def/coordinateOperation/EPSG/0/15593\"/>\n"
            + "      <epsg:sourceGeographicCRS xlink:href=\"http://www.opengis.net/def/crs/EPSG/0/4979\"/>\n"
            + "    </epsg:CRSMetaData>\n"
            + "  </gml:metaDataProperty>"
            + "<gml:identifier codeSpace=\"OGP\">http://www.opengis.net/def/area/EPSG/0/1262</gml:identifier>";

    String patternString1 = "(http(s)?://.*/def/.*)";

    Pattern pattern = Pattern.compile(patternString1);
    Matcher matcher = pattern.matcher(text);

    String prefixDomain = "http://localhost:8080/def";

    StringBuffer sb = new StringBuffer();

    while (matcher.find()) {
        String url = prefixDomain + matcher.group(1).split("def")[1];
        matcher.appendReplacement(sb, url);
        System.out.println(url);
    }
    matcher.appendTail(sb);
    System.out.println(sb.toString());

返回输出https://www.diffchecker.com/CyJ8fY8p

【讨论】:

    猜你喜欢
    • 2019-12-29
    • 2013-12-31
    • 2011-11-11
    • 2012-05-20
    • 1970-01-01
    • 2016-06-23
    • 2012-09-05
    • 2021-10-23
    相关资源
    最近更新 更多