【问题标题】:Find an replace Guid to binary equivalent with regular expression使用正则表达式查找二进制等效项的替换 Guid
【发布时间】:2014-03-14 09:13:28
【问题描述】:

我有一个字符串,其中包含带有 Guid 的常规 SQL 语句。应该转换该语句,以便我可以针对无法处理 .NET-Framework 描述的 Guid 的本地 SQLite 数据库运行它。 因此,我必须将它们转换为二进制表示形式,这意味着 Guid(在 SQL 中)'00000000-0000-0000-0000-000000000000' 将变为 X'000000000000000000000000000000000' 对于 SQLite 或 'FE334797-0A46-468D-91F2-0 ' 将变为 X'974733fe460a8d4691f20005f1ec67ec'。

单个Guid的转换方法如下:

private static string GetBinaryGuid(Guid guidToConvert)
{
    var guidBytes = guidToConvert.ToByteArray();
    var guidBinary = new StringBuilder();
    foreach (var guidByte in guidBytes)
    {
        guidBinary.AppendFormat(@"{0}", guidByte.ToString("x2"));
    }
    return guidBinary.ToString();
}

在查询字符串中找到真​​正的 Guid(s) 的方法是:

resultString = Regex.Replace(subjectString, @"\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}\b", "'$0'", RegexOptions.IgnoreCase);

我的问题是如何用它们各自的二进制等价物替换字符串中的“真实”Guid?

编辑:只是为了澄清。我想获取字符串中的所有 Guid,将找到的 Guid 传递给上面提到的方法并在字符串中替换它。 如果在字符串中找到,结果应该是带有二进制 Guid 的 SQL 查询。

编辑2:

SELECT * FROM table WHERE Id = 'FE334797-0A46-468D-91F2-0005F1EC67EC'

应该变成

SELECT * FROM table WHERE Id = X'974733fe460a8d4691f20005f1ec67ec'

编辑3:

@aelor 让我找到了正确的方向。 对于我的具体情况,可以在here 找到解决方案。

【问题讨论】:

  • SQL 字符串是完全任意的,还是总是采用某种已知的形式?
  • 没有。查询字符串可以包含任意数量的 Guid。甚至没有
  • 为什么不简单地将 GUID 存储为字符串?除了节省少量存储空间之外,转换为二进制形式进行存储还有什么好处(大概只有在数据检索时才再次转换回字符串形式)?如果您绝对必须转换数据,为什么不在 SQLite 本身中这样做(例如,使用触发器进行写入,使用视图进行读取)?
  • @eggyal:查询将首先在 SQL-Server 上执行。如果查询是您所期望的,则将其添加到系统中,系统会将其推送到客户端应用程序,客户端应用程序将在那里执行查询(针对 SQLite)。所以这只是为了简单。在SQL中添加语句并在后面进行转换,以便可以在客户端执行。触发器会为此付出太多努力。这只是一个不错的功能
  • 为什么如果需要,为 SQL 服务器生成代码的应用程序不为 SQLite 生成适当的查询,而不是尝试通过字符串转换来执行此操作?或者将足够的状态传递给客户端以使其生成语句?通过字符串操作执行此操作,而不解析 SQL,恕我直言,编程很糟糕。

标签: c# sql regex sqlite guid


【解决方案1】:

我知道这非常大,但这就是我能想到的:

\b([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})-([A-F0-9]{2})([A-F0-9]{2})-([A-F0-9]{2})([A-F0-9]{2})-([A-F0-9]{2})([A-F0-9]{2})-([A-F0-9]{12})\b

使用它,您将在匹配的组中获得结果。

替换字符串如下所示:

X'\4\3\2\1\6\5\8\7\9\10\11'

使用\L 将其设为小写。\

Demo here

如果你遇到这样的问题:

'X'974733FE460A91F20005F1EC67EC''

您可以使用函数轻松删除前导和尾随'

public class Main {   
  /**
   * Remove the leading and trailing quotes from <code>str</code>.
   * E.g. if str is '"one two"', then 'one two' is returned.
   *
   *
   * @return The string without the leading and trailing quotes.
   */
  static String stripLeadingAndTrailingQuotes(String str)
  {
      if (str.startsWith("\'"))
      {
          str = str.substring(1, str.length());
      }
      if (str.endsWith("\'"))
      {
          str = str.substring(0, str.length() - 1);
      }
      return str;
  }

}

【讨论】:

  • 太棒了。这几乎是我想要的。但我也需要替换单个配额:'Guid-Value' -> X'Binary-Value'。这个怎么加?
  • 你能详细说明一下吗?我不明白,你在说哪些引用
  • SQL is not a regular language,因此仅靠正则表达式无法解决这个问题。
  • @eggyal 你是对的,但这里将其视为一个必须替换的简单字符串。
  • @aelor 我的意思是单引号 ' 也应该在替换中。因为如果我替换 '00000000-0000-0000-0000-000000000000' 它将变成 'X'00000000000000000000000000000000'' 而不是 X'00000000000000000000000000000000' 而已。
猜你喜欢
  • 2012-06-06
  • 1970-01-01
  • 2023-03-21
  • 2014-11-18
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多