我有一个文本块,需要从中提取&替换某些出现的文本。我正在寻找的模式在这个序列中有5个组件:
1) /*<<@*/
2) any characters & symbols except this symbol combo: /*
3) /*
4) any upper or lower case letter, number, space or underscore
5) */
例如,到目前为止,我还无法设计出一个正则表达式模式,可以从文本中提取该模式的3个出现:
DECLARE @myDate DATETIME = /*<<@*/ '2018-07-20 00:00:00' /*My Date>>*/
DECLARE @myString VARCHAR(MAX) = /*<<@*/ 'whatever?' /*My String>>*/ DECLARE @isTrue VARCHAR(MAX) = /*<<@*/ 1 /*My Bool>>*/
以下是应该找到的3种情况:
1) /*<<@*/ '2018-07-20 00:00:00' /*My Date>>*/
2) /*<<@*/ 'whatever?' /*My String>>*/
3) /*<<@*/ 1 /*My Bool>>*/
但我总是出现2次——第二行被认为是单个匹配,而不是2个匹配:
1) /*<<@*/ '2018-07-20 00:00:00' /*My Date>>*/
2) /*<<@*/ 'whatever?' /*My String>>*/ DECLARE @isTrue VARCHAR(MAX) = /*<<@*/ 1 /*My Bool>>*/
下面是一个正则表达式模式的例子,这是我尝试过的许多模式之一:
(/*<<@*/){1}(.*){1}([a-z]|[A-Z]|[0-9]|_|s)*(>>*/){1}
如果我将第三个DECLARE移到它自己的行上,它是有效的(因为.符号在返回行处停止(,但当它们在同一行上时,我需要能够单独提取它们。
我已经使用regexr.com和regexstorm.net针对文本测试了我的所有模式。我的模式在第二个组件上进行了分解:除了/*
,我找不到在模式中包含任何字符或符号的方法,regex总是抓取太多。我试过/*
的负面广告。我尝试过显式指定所有有效字符,但找不到与/*
组合不匹配的方法。
任何帮助都将不胜感激!
这似乎对我有用:(/*<<@*/)((?:[^/]|/(?!*))+?)(/*)((?:[^*]|*(?!/))+?)(*/)
生成5个捕获组,如下所示:https://regex101.com/r/rd1Tl9/1
关键方面是这种模式:((?:[^/]|/(?!*))+?)
它说:找到任何不是/
的字符,或者在之后找到一个没有*
的。
这允许您获取与分隔符不匹配的部分。
您可以使用以下正则表达式:
/*<<@*/(?:(?!/*)[sS])*?/*+[^*]**+(?:[^/*][^*]**+)*/
请参阅regex演示。如果您需要将正则表达式用作正则表达式文字,请记住转义正斜杠:
//*<<@*/(?:(?!/*)[sS])*?/*+[^*]**+(?:[^/*][^*]**+)*//
如果您需要在C#中使用它,请将其定义为
var pattern = @"(?s)/*<<@*/(?:(?!/*).)*?/*+[^*]**+(?:[^/*][^*]**+)*/";
详细信息
/*<<@*/
-文字/*<<@*/
子字符串(?:(?!/*)[sS])*?
-不启动/*
序列的任何字符,零次或多次出现,尽可能少/*+[^*]**+(?:[^/*][^*]**+)*/
-一个C风格的注释正则表达式