You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java从位置随机的URL中提取两位国家代码(无需硬编码)

如何在Java中不硬编码国家代码提取URL中的两位国家代码

这问题挺常见的,我之前处理多区域URL解析需求时也碰过类似场景,给你分享几个实用的思路,完全不用硬编码所有国家代码就能搞定:

思路一:提取候选片段 + 匹配ISO标准国家代码集合

核心逻辑是:先从URL里找出所有可能的两位字母片段,再用Java自带的ISO标准国家代码集合做校验,筛选出有效的国家代码。

步骤拆解

  • 获取ISO 3166-1的两位国家代码全集:Java的Locale.getISOCountries()方法直接返回所有标准两位国家代码,不用自己手动维护列表。
  • 用正则或字符串拆分提取URL中不同位置的两位字母候选(域名后缀、路径中的xx-xx格式、路径单独段等)。
  • 对比候选和标准集合,筛选出有效代码,同时可以结合语言代码集合排除误判(比如把语言代码当成国家代码)。

代码示例

import java.util.*;
import java.util.regex.*;
import java.util.stream.Collectors;

public class CountryCodeExtractor {
    public static List<String> extractCountryCodesFromUrl(String url) {
        // 获取标准两位国家代码集合(转小写方便匹配)
        Set<String> validCountryCodes = Arrays.stream(Locale.getISOCountries())
                .map(String::toLowerCase)
                .collect(Collectors.toSet());
        // 获取标准两位语言代码集合(用于排除误判)
        Set<String> languageCodes = Arrays.stream(Locale.getISOLanguages())
                .map(String::toLowerCase)
                .collect(Collectors.toSet());
        
        List<String> result = new ArrayList<>();
        String lowerUrl = url.toLowerCase();

        // 1. 匹配域名后缀的国家代码(如.uk)
        Pattern domainSuffixPattern = Pattern.compile("\\.([a-z]{2})(?:/|$)");
        Matcher domainMatcher = domainSuffixPattern.matcher(lowerUrl);
        while (domainMatcher.find()) {
            String code = domainMatcher.group(1);
            if (validCountryCodes.contains(code)) {
                result.add(code.toUpperCase());
            }
        }

        // 2. 匹配路径中的xx-xx格式(如/de-de,取第二个代码)
        Pattern langCountryPattern = Pattern.compile("/([a-z]{2})-([a-z]{2})(?:/|$)");
        Matcher langCountryMatcher = langCountryPattern.matcher(lowerUrl);
        while (langCountryMatcher.find()) {
            String countryCode = langCountryMatcher.group(2);
            if (validCountryCodes.contains(countryCode)) {
                result.add(countryCode.toUpperCase());
            }
        }

        // 3. 匹配路径中单独的两位字母段(可选,需谨慎)
        Pattern standalonePattern = Pattern.compile("/([a-z]{2})(?:/|$)");
        Matcher standaloneMatcher = standalonePattern.matcher(lowerUrl);
        while (standaloneMatcher.find()) {
            String code = standaloneMatcher.group(1);
            // 是国家代码且不是语言代码时加入结果
            if (validCountryCodes.contains(code) && !languageCodes.contains(code)) {
                result.add(code.toUpperCase());
            }
        }

        // 去重并保持顺序
        return new ArrayList<>(new LinkedHashSet<>(result));
    }

    public static void main(String[] args) {
        System.out.println(extractCountryCodesFromUrl("www.abc.com.uk/services")); // [UK]
        System.out.println(extractCountryCodesFromUrl("www.prices.com/de-de")); // [DE]
        System.out.println(extractCountryCodesFromUrl("www.customers.com/fr-fr/services")); // [FR]
    }
}

思路说明

  • 用Locale类的API获取标准代码,完全避免硬编码,后续ISO标准更新时Java会同步维护。
  • 分场景匹配不同位置的候选,减少误判;比如xx-xx格式中优先取第二个代码作为国家代码(符合常见的语言-国家命名规范)。
  • 最后去重,避免同一个URL中出现多次相同的国家代码。

思路二:结构化解析URL + 标准代码校验

如果URL格式比较规范,用Java的URL类解析结构后再处理会更稳妥,避免正则的一些边缘情况。

步骤拆解

  • 用java.net.URL类解析URL的主机、路径等部分。
  • 主机部分拆分后缀,提取最后两位字母匹配国家代码。
  • 路径部分拆分各个段,分别处理xx-xx格式和单独两位字母段。
  • 同样用标准代码集合做校验筛选。

代码示例

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

public class CountryCodeUrlParser {
    public static List<String> extractCountryCodes(String url) throws MalformedURLException {
        Set<String> validCountryCodes = Arrays.stream(Locale.getISOCountries())
                .map(String::toLowerCase)
                .collect(Collectors.toSet());
        Set<String> languageCodes = Arrays.stream(Locale.getISOLanguages())
                .map(String::toLowerCase)
                .collect(Collectors.toSet());
        
        List<String> result = new ArrayList<>();
        URL parsedUrl = new URL(url);

        // 处理主机部分的国家代码
        String host = parsedUrl.getHost().toLowerCase();
        String[] hostParts = host.split("\\.");
        if (hostParts.length >= 2) {
            String lastPart = hostParts[hostParts.length - 1];
            if (lastPart.length() == 2 && validCountryCodes.contains(lastPart)) {
                result.add(lastPart.toUpperCase());
            }
        }

        // 处理路径部分
        String path = parsedUrl.getPath().toLowerCase();
        if (!path.isEmpty()) {
            String[] pathSegments = path.split("/");
            for (String segment : pathSegments) {
                if (segment.contains("-")) {
                    String[] langCountry = segment.split("-");
                    if (langCountry.length == 2) {
                        String countryCode = langCountry[1];
                        if (countryCode.length() == 2 && validCountryCodes.contains(countryCode)) {
                            result.add(countryCode.toUpperCase());
                        }
                    }
                } else if (segment.length() == 2) {
                    if (validCountryCodes.contains(segment) && !languageCodes.contains(segment)) {
                        result.add(segment.toUpperCase());
                    }
                }
            }
        }

        // 去重
        return new ArrayList<>(new LinkedHashSet<>(result));
    }

    public static void main(String[] args) throws MalformedURLException {
        System.out.println(extractCountryCodes("www.abc.com.uk/services")); // [UK]
        System.out.println(extractCountryCodes("www.prices.com/de-de")); // [DE]
        System.out.println(extractCountryCodes("www.customers.com/fr-fr/services")); // [FR]
    }
}

思路说明

  • 结构化解析URL更清晰,比如主机部分的拆分不会受到路径中字符的干扰。
  • 同样依赖Locale的标准代码,无需硬编码。
  • 对于路径段的处理更直观,适合URL格式比较规范的场景。

注意事项

  • 重叠代码处理:有些两位代码既是语言代码也是国家代码(比如fr是法语也是法国的国家代码),如果业务上需要区分,可以结合URL的上下文(比如域名后缀、路径层级)做进一步判断,或者让业务逻辑处理这类模糊情况。
  • 大小写兼容:统一转成小写或大写后再匹配,避免URL大小写不一致导致的漏判。
  • 边缘情况:比如co.uk这类域名,直接取最后两位uk即可,因为uk本身是标准国家代码,无需额外处理二级域名。

内容的提问来源于stack exchange,提问作者linuxman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:20:55