我有200k行的csv文件和3种MAC地址定义为:
我的目标是只留下以冒号分隔的形式。
所以将-
转换为:
并不重要:
mac = mac.replace("-", ":");
但如何将ECE1A9312000
转换为EC:E1:A9:31:20:00
。
我认为使用正则表达式但是使用组来获取这么多数据(~80k)太贵了。
我是否需要遍历每个char
并附加:
像:
for(int i=0; i<mac.length(); i++){
ch = mac.charAt(i);
if(i % 2 == 0 && i != 0){
tmp += ':';
}
tmp += ch;
}
还是有更有效的方式?
谢谢,
答案 0 :(得分:2)
我根据您丢弃的正则表达式方法将一个完全未经优化的程序整合在一起并计时。它在650毫秒内完成(预热250毫秒)。最慢的部分不涉及正则表达式,而是String.format
。如果我们用直接StringBuilder
方法替换它,时间会下降到40毫秒。
public class Test {
static Pattern regex = Pattern.compile("(..)(..)(..)(..)(..)(..)");
public static void main(String[] args) {
final List<String> inMacs = new ArrayList<>(), outMacs = new ArrayList<>();
for (int i = 0; i < 80_000; i++) inMacs.add(mac());
final long start = System.nanoTime();
for (String mac : inMacs) {
final Matcher m = regex.matcher(mac);
m.matches();
outMacs.add(String.format("%s:%s:%s:%s:%s:%s",
m.group(1), m.group(2), m.group(3), m.group(4), m.group(5), m.group(6)));
}
System.out.println("Took " + (System.nanoTime() - start)/1_000_000 + " milliseconds");
final Iterator<String> it = outMacs.iterator();
for (int i = 0; i < 100; i++) System.out.println(it.next());
}
static Random rnd = new Random();
static String mac() {
final long mac = (long) (rnd.nextDouble()*(1L<<48));
return String.format("%012x", mac).toUpperCase();
}
}
如果您真的在寻找快速解决方案,请避免使用正则表达式并使用简单的测试来检测您的MAC格式:
static List<String> fixMacs(List<String> inMacs) {
final List<String> outMacs = new ArrayList<>(inMacs.size());
for (String mac : inMacs) outMacs.add(
mac.charAt(2) == '-'? mac.replace("-", ":")
: mac.charAt(2) != ':'? fixMac(mac)
: mac);
return outMacs;
}
static String fixMac(String inMac) {
final StringBuilder b = new StringBuilder(18);
for (int i = 0; i < inMac.length(); i++) {
b.append(inMac.charAt(i));
if (i%2 == 1 && i != inMac.length()-1) b.append(':');
}
return b.toString();
}
通过这种方法,我测得的80,000 MAC仅为8 ms。
答案 1 :(得分:1)
逐个字符地迭代它,如果找到的字符为' - '则每两步一次用':'替换它,如果是字母或数字,则插入':'字符。
答案 2 :(得分:1)
试试这个
String x="ECE1A9312000";
String finals="";
for(int i=0;i<x.length();i=i+2)
{
if((i+2)<x.length())
finals+=x.substring(i, i+2)+":";
if((i+2)==x.length())
{
finals+=x.substring(i, i+2);
}
}
System.out.println(finals);
<强>输出 EC:E1:A9:31:20:00
答案 3 :(得分:1)
使用正则表达式分割每2个字符,并使用String.join
与分隔符连接:
public static String convertToColonSeparatedMac(String mac) {
if (mac.contains(":"))
return mac;
if (mac.contains("-"))
return mac.replaceAll("-", ":");
return String.join(":", mac.split("(?<=\\G.{2})"));
}
您可以在转换前验证它:
private static final Pattern MAC_PATTERN = Pattern.compile("(^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$)|([0-9A-Fa-f]{12})");
public static boolean isValidMac(String mac) {
return MAC_PATTERN.matcher(mac).matches();
}
答案 4 :(得分:0)
String mac[] = {"ECE1A9312000", "24-C9-A1-15-89-B0", "E8:6D:52:75:2D:16"};
for (int i = 0; i< mac.length; i++)
{
if (mac[i].charAt(2) == '-')
mac[i] = mac[i].replace("-", ":");
else if (mac[i].charAt(2) != ':')
mac[i] = new StringBuilder(mac[i].substring(0,2)).append(":").append(mac[i].substring(2,4))
.append(":").append(mac[i].substring(4,6)).append(":").append(mac[i].substring(6,8))
.append(":").append(mac[i].substring(8,10)).append(":").append(mac[i].substring(10)).toString();
}
for (int i = 0; i< mac.length; i++)
System.out.println(mac[i]);
输出:
EC:E1:A9:31:20:00
24:C9:A1:15:89:B0
E8:6D:52:75:2D:16