我有一段文本需要从中提取并替换某些出现的文本。我要寻找的模式按以下顺序包含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针对文本测试了所有模式。我的模式在第二个组件上分解:除了/*
之外,我找不到在模式中包含任何字符或符号的方法,正则表达式总是占用太多空间。我已经尝试了/*
的负面预测。我尝试显式指定所有有效字符,但找不到与/*
组合不匹配的方法。
任何帮助将不胜感激!
答案 0 :(得分:1)
这似乎对我有用:
(\/\*<<@\*\/)((?:[^\/]|\/(?!\*))+?)(\/\*)((?:[^*]|\*(?!\/))+?)(\*\/)
产生5个捕获组,如下所示:https://regex101.com/r/rd1Tl9/1
关键方面是这种模式:
((?:[^\/]|\/(?!\*))+?)
表示:找到所有不是/
的字符,或者随后找到没有\
的{{1}}。
这使您可以抓取与分隔符不匹配的部分。
答案 1 :(得分:1)
您可以使用以下正则表达式:
/\*<<@\*/(?:(?!/\*)[\s\S])*?/\*+[^*]*\*+(?:[^/*][^*]*\*+)*/
请参见regex demo。如果需要将正则表达式用作正则表达式文字,请记住转义正斜杠:
/\/\*<<@\*\/(?:(?!\/\*)[\s\S])*?\/\*+[^*]*\*+(?:[^\/*][^*]*\*+)*\//
如果您需要在C#中使用它,请将其定义为
var pattern = @"(?s)/\*<<@\*/(?:(?!/\*).)*?/\*+[^*]*\*+(?:[^/*][^*]*\*+)*/";
详细信息
/\*<<@\*/
-文字/*<<@*/
子字符串(?:(?!/\*)[\s\S])*?
-不会开始/*
序列的任何字符,零个或多个出现(尽可能少)/\*+[^*]*\*+(?:[^/*][^*]*\*+)*/
-一个C-style comment regex。