【问题标题】:Regular Expression to work on different locales正则表达式适用于不同的语言环境
【发布时间】:2026-01-12 00:35:01
【问题描述】:

我在java中使用ipconfig/all命令和正则表达式来查找MAC地址。

我在ipconfig/all 命令的输出中搜索Physical Address

但问题是我希望正则表达式适用于不同的语言环境,即它可以找到任何语言环境的物理地址。

提前致谢。

【问题讨论】:

  • 您可以尝试检查 MAC 地址本身 - IIRC Windows 以 01-23-45-67-89-ab 的格式显示它

标签: java regex


【解决方案1】:

无需搜索“物理地址”或任何其他本地化版本(每次需要支持新语言时都需要添加本地化版本),您只需编写一个正则表达式即可找到 MAC地址本身。

由于我们知道一个典型的 MAC 地址由六个分组组成,每个分组有两个十六进制数字,用冒号、句点或破折号分隔,下面的正则表达式可以做到这一点:

([a-fA-F0-9]{2}[:\-\.]){5}[a-fA-F0-9]{2}

说明: (两个十六进制数字后跟一个冒号 :,重复 5 次)(最后两个十六进制数字)

【讨论】:

  • 次要更正:Windows 部分使用其自己的约定,因此您需要用破折号替换冒号 -(唉,并非无处不在 - 有时使用 -,有时使用 : ,有时什么都没有;这个特殊的用途有破折号)
  • 啊,好点子。我更新了正则表达式以允许使用冒号、点或破折号。根据需要添加任意数量的特殊字符。在某些情况下,我想不会有分隔符。如果您正在处理这样的情况,您还可以通过正则表达式中的? 将分隔符设为可选。
【解决方案2】:

这是我运行 ipconfig /all 时得到的结果:

Adaptér sítě Ethernet Připojení k místní síti:
        Přípona DNS podle připojení . . . : example.com
        Popis . . . . . . . . . . . . . . : AMD PCNET Family PCI Ethernet Adapter
        Fyzická Adresa. . . . . . . . . . : DE-AD-BE-EF-CA-FE
        Protokol DHCP povolen . . . . . . : Ano
        Automatická konfigurace povolena  : Ano
        Adresa IP . . . . . . . . . . . . : 192.168.0.158
        Maska podsítě . . . . . . . . . . : 255.255.255.0
        Výchozí brána . . . . . . . . . . : 192.168.0.1
        Server DHCP . . . . . . . . . . . : 192.168.0.1
        Servery DNS . . . . . . . . . . . : 192.168.0.1
        Primární server WINS. . . . . . . : 192.168.0.1
        Zapůjčeno . . . . . . . . . . . . : 9. září 2011 16:05:32
        Zápůjčka vyprší . . . . . . . . . : 9. září 2011 20:05:32

如您所见,查找字符串“物理地址”有点徒劳,因为没有。但是,请注意,Windows 有自己的 MAC 地址格式 - 用连字符分隔每两个十六进制数字(字母部分大写)。所以,寻找正则表达式:

([0-9A-F]{2}-){5}[0-9A-F]{2}

将为您提供您正在寻找的 MAC 地址。

警告:许多计算机具有多个网络接口(有线和 wifi、各种 VPN 等),因此输出中可能会发现多个 MAC。

【讨论】:

  • saakra toto je anglicke 论坛 :-) - 这是英语论坛,顺便说一句 +1
  • @mKorbel:我有点意识到这一点。正如您可能从第 2 段中注意到的那样,我正在使用本地化文本来显示字符串 Physical address 可能不存在于输出中,而 making a list of all possible l10ns 有点无用 - 这就是我建议直接查找 MAC 的原因地址。
【解决方案3】:

注意某些计算机,尤其是 HP/Compaq MAC 地址应该可以从

访问
Process pcs = Runtime.getRuntime().exec("wmic bios"); 

如果 BIOS 是定制的(最大的公司),那么这些数据应该可以通过使用 JNI/JNA 访问(周围有很多 VB/C# 脚本)

示例:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public class MAC_TEST {

    private static Pattern macPattern = Pattern.compile("[0-9a-fA-F]{2}[-:][0-9a-fA-F]{2}[-:]"
            + "[0-9a-fA-F]{2}[-:][0-9a-fA-F]{2}[-:][0 -9a-fA-F]{2}[-:][0-9a-fA-F]{2}");

    private static List getWindowsMACAddresses() {
        try {
            //Process conf = Runtime.getRuntime().exec("wmic bios");//for HP computers
            Process conf = Runtime.getRuntime().exec("ipconfig /all");
            //Process p = Runtime.getRuntime().exec("wmic bios /all");
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(conf.getInputStream()));
            return getMACAddresses(input);
        } catch (Exception e) {
            System.err.println("Error Reading Windows MAC Address.");
        }
        return new ArrayList(1);
    }

    private static List getLinuxMACAddresses() {
        try {
            Process conf = Runtime.getRuntime().exec("/sbin/ifconfig");
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(conf.getInputStream()));
            return getMACAddresses(input);
        } catch (Exception e) {
            System.err.println("Error Reading Linux MAC Address.");
        }
        return new ArrayList(1);
    }

    private static List getHPUXMACAddresses() {
        try {
            Process conf = Runtime.getRuntime().exec("/etc/lanscan");
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(conf.getInputStream()));
            return getMACAddresses(input);
        } catch (Exception e) {
            System.err.println("Error Reading HPUX MAC Address.");
        }
        return new ArrayList(1);
    }

    private static List getSolarisMACAddresses() {
        try {
            List rtc = new ArrayList(1);
            Process conf = Runtime.getRuntime().exec("/usr/sbin/arp "
                    + InetAddress.getLocalHost().getHostAddress());
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(conf.getInputStream()));
            rtc.addAll(getMACAddresses(input));
            input.close();
            input = null;
            conf = null;
            //Solaris reports MAC address without first 0, change the pattern at re-test
            macPattern = Pattern.compile("[0-9a-fA-F][-:][0-9a-fA-F]{2}[-:][0-9a-fA-F]{2}"
                    + "[-:][0-9a-fA-F]{2}[-:][0 -9a-fA-F]{2}[-:][0-9a-fA-F]{2}");
            conf = Runtime.getRuntime().exec("/usr/sbin/arp "
                    + InetAddress.getLocalHost().getHostAddress());
            input = new BufferedReader(new InputStreamReader(
                    conf.getInputStream()));
            rtc.addAll(getMACAddresses(input));
            //Revert pattern
            macPattern = Pattern.compile("[0-9a-fA-F]{2}[-:][0-9a-fA-F]{2}[-:][0-9a-fA-F]{2}"
                    + "[-:][0-9a-fA-F]{2}[-:][0 -9a-fA-F]{2}[-:][0-9a-fA-F]{2}");
            return rtc;
        } catch (Exception e) {
            System.err.println("Error Reading Solaris MAC Address.");
        }
        return new ArrayList(1);
    }

    private static List getMACAddresses(BufferedReader input) throws Exception {
        List MACs = new ArrayList(1);
        String theLine;
        while ((theLine = input.readLine()) != null) {
            String[] ss = macPattern.split(theLine);
            for (int p = 0; p < ss.length; p++) {
                String s = theLine.substring(theLine.indexOf(ss[p]) + ss[p].length()).trim();
                if (!s.isEmpty()) {
                    String s1 = s.replaceAll("-", ":");
                    String s2 = s1.substring(0, s1.lastIndexOf(':') + 3);
                    if (s2.length() == 16 || s2.length() == 17) {
                        MACs.add(s2);
                    }
                }
            }
        }
        return MACs;
    }

    public static void main(String[] args) {
        try {
            System.out.println("WINDOWS ... Found the following MAC Addresses: ");
            List MACS = getWindowsMACAddresses();
            System.out.println("*-----------------*");
            for (int i = 0; i < MACS.size(); i++) {
                System.out.println("|" + MACS.get(i) + "|");
            }
            System.out.println("*-----------------*");
            System.out.println(" ");
            System.out.println("Linux ...  Found the following MAC Addresses: ");
            MACS = getLinuxMACAddresses();
            System.out.println("*-----------------*");
            for (int i = 0; i < MACS.size(); i++) {
                System.out.println("|" + MACS.get(i) + "|");
            }
            System.out.println("*-----------------*");
            System.out.println(" ");
            System.out.println("Solaris ...  Found the following MAC Addresses: ");
            MACS = getSolarisMACAddresses();
            System.out.println("*-----------------*");
            for (int i = 0; i < MACS.size(); i++) {
                System.out.println("|" + MACS.get(i) + "|");
            }
            System.out.println("*-----------------*");
            System.out.println(" ");
            System.out.println("HPUX ...  Found the following MAC Addresses: ");
            MACS = getHPUXMACAddresses();
            System.out.println("*-----------------*");
            for (int i = 0; i < MACS.size(); i++) {
                System.out.println("|" + MACS.get(i) + "|");
            }
            System.out.println("*-----------------*");
            System.out.println(" ");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private MAC_TEST() {
    }
}

【讨论】:

    【解决方案4】:

    选项 1:

    您可以使用这样的正则表达式(英语、法语、西班牙语):

    /(Physical Address|Adresse Physique|Direccion fisica)/
    

    稍后检查您使用的语言环境并相应地更新您的正则表达式。

    选项 2:

    直接使用Java(JDK 1.6)获取MAC地址

    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class MacAddress {
    
    public static void main(String[] args) {
        try {
            //InetAddress address = InetAddress.getLocalHost();
            InetAddress address = InetAddress.getByName("192.168.0.158");
    
            /*
             * Get NetworkInterface for the current host and then read the
             * hardware address.
             */
            NetworkInterface ni = NetworkInterface.getByInetAddress(address);
            if (ni != null) {
                byte[] mac = ni.getHardwareAddress();
                if (mac != null) {
                    /*
                     * Extract each array of mac address and convert it to hexa with the
                     * following format 08-00-27-DC-4A-9E.
                     */
                    for (int i = 0; i < mac.length; i++) {
                        System.out.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "");
                    }
                } else {
                    System.out.println("Address doesn't exist or is not accessible.");
                }
            } else {
                System.out.println("Network Interface for the specified address is not found.");
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    

    }

    【讨论】:

    • 1) 这将中断不在列表中的语言(XP 至少支持大约 30 种语言版本),2) 因为这是ipconfig,而不是iptables - Windows 的源代码不会随时可用,这意味着您需要获得各种语言的所有安装并获得相应的描述。 3) 如果描述在新版本的 Windows 中发生变化,那么你将有祸了。