我有以下正则表达式,用于查找需要解析的文件区域:
public static readonly Regex ObjectAction = new Regex($@"(?<Shape>{GetShapeOrRegexSnippet}).+?userdata\s"".*?action=(?<ActionType>\w+)\^(?<ActionPropertyString>.*?)\^\""", RegexOptions.Singleline);
哪里GetShapeOrRegexSnippet
定义为:
private static string GetShapeOrRegexSnippet => ShapeCodes.Aggregate((i, j) => i + '|' + j);
匹配遇到 ShapeCodes
之一之间(并包括)的区域在我的收藏中( rect
、 circ
、 line
等)和以 . userdata
开头的行。这对于结构良好的部分效果很好,例如:
line \
16.5894 34.4828 34.8993 46.3054 19.6616 41.3793 \
11.6741 44.9507
. filled 1
. dynprop \
(FOX_VAR_3 \
(= * \
(ecolor FOX_VAR_3))) \
(o2 \
(= * \
(call fox_oos(__self))))
. userdata "FOX_VAR=3^attr=ECOLOR^attrval=3^required=0^var=UPDATETAG33^delta=1.000000^conv=LOOKUP^type=LONG^minstate=0^num_entries=2^entries=7,7^END_FOXV= ^oos_obj=0002"
但是,给定形状完全有可能没有关联的 userdata
字符串,那么是否可以规定如果Regex
遇到 ShapeCodes
中的任何一个在遇到userdata
之前再一次string 它不会匹配该部分并将继续检查文件的其他部分?
我最初的想法是使用否定前瞻,但这不起作用(我对 Regex
还很陌生,所以我可能做错了什么):
(?<Shape>rect|frect|fpie|spline|poly|line|fsec|fcir).+?(?!rect|frect|fpie|spline|poly|line|fsec|fcir)userdata\s\".*?attr=(?<AttributeType>\w+)\^(?<AttributePropertyString>.*?)\^(?=(?:END_FOXV))
这可能吗?如果是这样,请您指出正确的方向,如果不是,请告诉我,我会尝试不同的方法。
最佳答案
要点是 .+?
匹配尽可能少的任何 1+ 个字符,但是来自 {GetShapeOrRegexSnippet}
的第一个匹配。这就是为什么它可能会跨越多个 block 进行匹配。
将第一个 .+?
替换为 (?:(?!{GetShapeOrRegexSnippet}|action=).)*
,这是一个调和的贪婪标记,只会匹配0+ 个不启动与 {GetShapeOrRegexSnippet}
或 action=
匹配的序列的字符。
关于c# - 如果在模式中间遇到字符串,则正则表达式不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41959505/