正则表达式提取复杂的模式,其中包括除特定符号组合之外的任何字符或符号

时间:2018-07-23 22:29:21

标签: regex

我有一段文本需要从中提取并替换某些出现的文本。我要寻找的模式按以下顺序包含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针对文本测试了所有模式。我的模式在第二个组件上分解:除了/*之外,我找不到在模式中包含任何字符或符号的方法,正则表达式总是占用太多空间。我已经尝试了/*的负面预测。我尝试显式指定所有有效字符,但找不到与/*组合不匹配的方法。

任何帮助将不胜感激!

2 个答案:

答案 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