java regex for UUID

2022-09-03 06:33:51

我想解析具有以下格式的UUID的字符串

"<urn:uuid:4324e9d5-8d1f-442c-96a4-6146640da7ce>"

我已经尝试了以下方式解析它,这有效,但我认为它会很慢

private static final String reg1 = ".*?";
private static final String reg2 = "([A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12})";
private static final Pattern splitter = Pattern.compile(re1 + re2, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

我正在寻找一种更快的方法,并在下面尝试,但它无法匹配

private static final Pattern URN_UUID_PATTERN = Pattern.compile("^< urn:uuid:([^&])+&gt");

我是正则表达式的新手。任何帮助都是值得赞赏的。

\阿库拉


答案 1

您的更快正则表达式示例是使用输入所在的位置,因此令人困惑。<&lt;

关于速度,首先,您的UUID是十六进制的,因此不要与匹配,而是与.其次,您没有给出大小写混合的指示,因此不要使用不区分大小写并在范围内编写正确的大小写。A-Za-f

您没有解释是否需要 UUID 前面的部分。如果没有,请不要包含 ,您也可以在 .也没有迹象表明你需要DOTALL。.*?re1re2final Pattern

private static final Pattern splitter =
  Pattern.compile("[a-f0-9]{8}(?:-[a-f0-9]{4}){4}[a-f0-9]{8}");

或者,如果您测量正则表达式的性能太慢,则可以尝试另一种方法,例如:
每个 uuid 前面是否都带有“uuid:”,如您的示例中所示?如果是这样,您可以

  1. 将“uuid:”的第一个索引查找为 i,然后
  2. 子字符串 0 到 i+5 [假设你完全需要它],以及
  3. 子字符串 i+5 到 i+41,如果我计算正确(长度为 36 个字符)。

沿着类似的思路,你更快的正则表达式可能是:

private static final Pattern URN_UUID_PATTERN =
    Pattern.compile("^&lt;urn:uuid:(.{36})&gt;");

OTOH,如果您的所有输入字符串都将以这些确切的字符开头,则无需在上一个建议中执行步骤1,只需input.substring(13, 49);


答案 2

如果此格式未更改。我认为更快速的方法是使用String.substring()方法。例:

String val = "&lt;urn:uuid:4324e9d5-8d1f-442c-96a4-6146640da7ce&gt;";
String sUuid = val.substring(13, 49);
UUID uuid =  UUID.fromString(sUuid);

在类 String 中使用 char 数组来存储数据,在 package java.lang.String 中:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
...
113: /** The value is used for character storage. */
114: private final char value[];
...
}

方法'String substring(int beginIndex, int endIndex)'制作数组元素的副本,从开始到结束索引,并在新数组的基础上创建新的字符串。复制数组是一个非常快速的操作。