繁体   English   中英

正则表达式:获取所有单个字符,但不是在单引号之间

[英]regex: get all of a single character, but not when between single quotes

我需要一个Regex表达式来捕获字符串中的所有冒号,但是当冒号位于单引号之间时,然后用at符号(@)替换它。

我的测试字符串是:

select id, :DATA_INI, ':DATA_INI', titulo, date_format(data_criacao,'%d/%m/%Y %H:%i') str_data_criacao
from v$sugestoes
where data_criacao between :DATA_INI AND :DATA_FIM
order by data_criacao

我真正想要的是:

select id, @DATA_INI, ':DATA_FIM', titulo, date_format(data_criacao,'%d/%m/%Y %H:%i') str_data_criacao
from v$sugestoes
where data_criacao between @DATA_INI AND @DATA_FIM
order by data_criacao

我试过这个正则表达式,但由于某种原因它没有捕获第一个冒号:

/(?!'.*?):(?!.*?')/g

在此输入图像描述 PS:有嵌套引号的可能性,这些字符串也不能被捕获。

谁知道我在这里失踪了什么? 我实际上在使用C#。

这可以做到:

:(?=([^']*'[^']*')*[^']*$)

RegEx测试仪

它只匹配那些跟随偶数引号的冒号(正面向前看)。 这也包括引号在引用字符串中被转义(对于SQL)的情况,因为它们之前是另一个引号,因此保持引号计数均匀。

正如评论中所述,这个正则表达式是相当低效的,因为它多次扫描字符串的某些部分:每次找到冒号时,扫描字符串的其余部分以查看(非转义)引号的数量是否为偶数。

但是对于SQL字符串,它似乎是你处理的字符串类型,这不应该是一个问题,它们通常是不是很长的字符串,也没有数百个引号或冒号。

C#解决方案

根据上述想法,您可以使用以下C#代码:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        // This is the input string we are replacing parts from.
        string input = "select id, :DATA_INI, ':DATA_INI', titulo, date_format(data_criacao,'%d/%m/%Y %H:%i') str_data_criacao\n"
            + "from v$sugestoes\n"
            + "where data_criacao between :DATA_INI AND :DATA_FIM AND ':TEST'\n"
            + "  and  'test ''string :DATA_INI '' :DATA_INI '\n"
            + "order by data_criacao";

        string output = Regex.Replace(input, ":(?=([^']*'[^']*')*[^']*$)", "@");

        Console.WriteLine(output);
    }
}

看它在ideone.com上运行。

由于您使用的是C#,请尝试:

Regex.Replace(input, @"(?<!'):(\w+)", "@$1")

这将匹配所有占位符,这些占位符不会直接' (负面观察背后)之前。

工作示例: https//dotnetfiddle.net/N43ipM

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM