使用C#

时间:2018-10-18 18:24:35

标签: c# regex string

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

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

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

最后一部分<special character>forced是可选的,可能存在也可能不存在,但如果存在forced,则必须在前面加上特殊字符(例如._或{ {1}})视为有效字符串。

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

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#的正则表达式实现我所需要的?

2 个答案:

答案 0 :(得分:1)

发布my suggestion,因为事实证明这很有帮助:

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

请参见regex demo

详细信息

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

答案 1 :(得分:0)

我发现您对nameeng无效的假设表明,对于标题的定义缺乏明确性。以下将适用于成功条件。请注意,使用IgnorePatternWhiteSpace可以按照以下所示的模式显示多行。

^
(?<Header>\w+)
[.\-\(\)_]*
(?<Code1>\w+)
[.\-\(\)_]*
(?<Code2>\w*)
[.\-\(\)_]*
(?<IsForced>forced)?