我想从字符串中提取标题和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#的正则表达式实现我所需要的?
答案 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)?