正则表达式中子串在特定位置未找到于模式中。

huangapple go评论64阅读模式
英文:

Regex where substring isn't found in pattern in specific location

问题

I am trying to build a (multiline) pattern for a linter, to catch cases where:

  1. There is a Text( declaration
  2. That is not followed by .appFont( declaration...
  3. ...before the next occurrence of } (end of function) or Text( (another Text declaration...)

After many hours on regex101 (and consulting gpt...) I got these 2:

Text\([\s\S]*?\)[\s\S]*?(?!\.appFont)

This just catches the part that's before the .appFont, but I want the entire catch to fail if .appFont is found...

Text\([\s\S]*?\)[\s]*?(?!appFont)[\s\S]\}

This just catches everything, ignoring appFont being in the sting entirely...

In the following example, only the 2nd case should be captured:

Text("blah") 
  .appFont(.body)
}

Text("blah") 
}

Text(
  "blah"
)
.appFont(.blah)
}

I tried to read about negative lookahead but I think I still somehow just use it wrong, or somehow cause it to be ignored when I add [\s\S] maybe?

英文:

I am trying to build a (multiline) pattern for a linter, to catch cases where:

  1. There is a Text( declaration
  2. That is not followed by .appFont( declaration...
  3. ...before the next occurrence of } (end of function) or Text( (another Text declaration...)

After many hours on regex101 (and consulting gpt...) I got these 2:

Text\([\s\S]*?\)[\s\S]*?(?!\.appFont)

This just catches the part that's before the .appFont, but I want the entire catch to fail if .appFont is found...

Text\([\s\S]*?\)[\s]*?(?!appFont)[\s\S]\}

This just catches everything, ignoring appFont being in the sting entirely...

In the following example, only the 2nd case should be captured:

Text("blah") 
  .appFont(.body)
}

Text("blah") 
}

Text(
  "blah"
)
.appFont(.blah)
}

I tried to read about negative lookahead but I think I still somehow just use it wrong, or somehow cause it to be ignored when I add [\s\S] maybe?

答案1

得分: 3

Using a negated character class together with a negative lookahead.

Text([^)])(?:(?!.appFont)[^}])}

See this demo at regex101 - A bit similar to tempered greedy token.

regex explanation
Text 匹配子串
\([^)]*\) 匹配 ( 后跟 任意数量) 否定类 直到下一个闭合 )
(?:(?!\.appFont)[^}])*} (?: 非捕获组) 重复 * 任意数量 次,包含:<br>(?!\.appFont) 在每个 } 前进行 否定 前瞻,检查子串 \.appFont 是否不在前面 - 在成功时消耗每个匹配字符直到 }

或者在关闭 ) 后仅使用前瞻断言一次。

Text([^)])(?![^}]?.appFont)[^}]*}

Another demo at regex101 - 在这里甚至可能更有效。

regex explanation
Text 匹配子串
\([^)]*\) 匹配 ( 后跟 任意数量) 直到下一个闭合 )
(?![^}]*?\.appFont) 否定前瞻 (条件): 查看 是否 [^}]*?\.appFont 不在其前面,其中 [^}]*? 惰性匹配 任意数量} 直到子串 \.appFont
[^}]*} 如果条件成功(它不在前面),则消耗 任意数量} 直到 }
英文:

Using a negated character class together with a negative lookahead.

Text\([^)]*\)(?:(?!\.appFont)[^}])*}

See this demo at regex101 - A bit similar to tempered greedy token.

regex explanation
Text match the substring
\([^)]*\) match ( followed by any amount of non-) negated class up to next closing )
(?:(?!\.appFont)[^}])*} (?: non capturing group) repeated * any amount of times, containing:<br>(?!\.appFont) a neg. lookahead that checks in front of each non-} if substring \.appFont is not ahead - consumes on success each matching character up to }

Or alternatively use the lookahead assertion just once after closing ).

Text\([^)]*\)(?![^}]*?\.appFont)[^}]*}

Another demo at regex101 - Might even be a bit more efficient here.

regex explanation
Text match the substring
\([^)]*\) match ( followed by any amount of non-) up to the next closing )
(?![^}]*?\.appFont) neg. lookahead (condition): look if [^}]*?\.appFont is not ahead where [^}]*? matches lazily any amount of non-} up to the substring \.appFont
[^}]*} if the condition succeded (it's not ahead) consume any amount of non-} up to }

huangapple
  • 本文由 发表于 2023年4月17日 21:22:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76035642.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定