使用C#中的Regex从字符串中提取带有可选特殊字符的代码?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (380)

我想从字符串中提取标题和2或3位ISO 639代码。

有效字符串的一般格式是:

header + <special char> + <2 or 3 digit code> + (<special char>forced)

最后一部分<special character>forced是可选的,可能存在也可能不存在,但如果存在,则forced必须在其前面加上特殊字符(如._-),以使其成为有效的字符串。

eng要提取的标头和语言代码()的有效字符串示例:

name.eng
name-eng
name(eng)
name(fri)_eng
name(fri)(eng)
name.eng.forced
name(eng).forced
name.(eng).forced
name.fri.eng.forced
name(fri).eng.forced
name.(fri).eng_forced
name-fri-eng.forced
name_(fri)_eng.forced
name(fri)_eng.forced
name(friday)_eng_forced
name(fri)(eng).forced

这里的一个检查是,如果语言代码有一个)后面,那么它必须有一个(之前。这并不重要,但如果正则表达式可以检查它会很好。

无效字符串的示例如下:

nameeng
nameeng.forced
name.eng).forced
name(fri)eng.forced
name(friday).engforced
name(fri)(eng)forced

我想出来检查这个是:

(.*)([._\-(])([a-z][a-z][a-z]|[a-z][a-z])((?<=\(...)\))?(.forced)?

我也在尝试非关键的回顾来检查(语言代码之前是否有)代码之后。这再次并不重要,但不是我面临的核心问题。

问题是标题(以及语言代码)对于某些有效名称是不正确的,因为我认为表达式太贪婪(我使用C#,无法关闭所有操作数的贪婪)。我尝试了从右到左的选项,但在重新排列表达式之后似乎没有用。

是否有可能通过C#中的Regex实现我的需求?

提问于
用户回答回答于

发布我的建议,因为它证明是有帮助的:

^(.*?[._-]?)(?=[\W_])[._-]?(\()?([a-z]{2,3})(?(2)\)|)(?:[_\W]forced)?$

请参阅正则表达式演示

细节

  • ^ - 字符串的开头
  • (.*?[._-]?)- 第1组:除了换行符之外的任何0+字符,尽可能少,然后是可选的._或者-
  • (?=[\W_])[._-]?(\()?- 下一个char必须是非字母数字字符(由于(?=[\W_])posititve lookahead),然后是可选的.-或者_是匹配的,然后是可选的(,被捕获到第2组中
  • ([a-z]{2,3}) - 2或3个小写ASCII字母
  • (?(2)\)|)- 条件构造:如果组2匹配,则匹配a ),else匹配空字符串
  • (?:[_\W]forced)? - 一个匹配1或0次出现的可选非捕获组
    • [_\W] - 任何非字母数字字符
    • forced - 子串

  • $ - 字符串结尾。
用户回答回答于

我通过使用End of Line锚点$并向后工作来实现它:

([a-zA-Z0-9]+)[)_.]*(forced)?$

https://regex101.com/r/Lc8xDN/1

忽略结束的可选forced文本和任何前面的特殊字符。接下来是你的比赛。

再次,回到前面这里是重要的一点。

扫码关注云+社区

领取腾讯云代金券