【问题标题】:java regex for UUIDUUID的java正则表达式
【发布时间】:2016-06-03 13:29:42
【问题描述】:

我想解析一个 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");

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

\阿库拉

【问题讨论】:

  • 等等,您的数据中有&amp;lt;...,但在您的正则表达式中使用^&lt;...?那是行不通的。
  • 提示:如果性能确实是个问题 - 请记住 UUID 的结构是固定的。它有固定的长度、固定的子字段等等。因此,使用对 substring() 的调用只是“编码工作”,例如“删除”您正在寻找的基本部分。然后您只需要检查输入的初始长度......换句话说:您搜索“uuid:”;然后你“substring()”冒号后面的 36 个字符;并从那里分开。
  • 您的reg2 错误。 UUID 是一个十六进制数字,因此只有字母 A 到 F。任何其他字母都是错误的。
  • 如果字符串的格式始终相同,即"&amp;lt;urn:uuid:&lt;actual uuid&gt;&amp;gt;",则表达式不会太复杂:&amp;lt;urn:uuid:(.*)&amp;gt;(或者甚至可能是uuid:([a-f0-9\-]+)
  • “但是我认为它会很慢” 你为什么这么认为?你真的测量过吗?

标签: java regex


【解决方案1】:

你的一个更快的正则表达式的例子是使用&amp;lt;,其中输入是&amp;lt;,所以这很混乱。

关于速度,首先,你的 UUID 是十六进制的,所以不要匹配 A-Z 而是匹配 a-f。其次,你没有给出大小写混合的指示,所以不要不区分大小写,并在范围内写正确的大小写。

你没有解释是否需要 UUID 前面的部分。如果没有,请不要包含.*?,您也可以将re1re2 的文字一起写在您的final Pattern 中。也没有迹象表明您需要 DOTALL。

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 数组存储数据,在包 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)' 复制数组元素,从开始到结束索引,并在新数组的基础上创建新字符串。 复制数组是一个非常快的操作。

    【讨论】:

      猜你喜欢
      • 2015-12-29
      • 2016-09-28
      • 2013-01-18
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-07
      相关资源
      最近更新 更多