我想从字符串中提取 header 和 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)?
我也在尝试非关键回顾来检查 (
在语言代码之前,如果它有 )
在代码之后。这又不是关键问题,但不是我面临的核心问题。
问题是一些有效名称的 header (以及相应的语言代码)不正确,因为我认为表达式太贪婪(我使用的是 C#,无法关闭所有操作数的贪婪)。我试过从右到左的选项,但在重新排列表达式后似乎也不起作用。
是否可以通过 C# 中的正则表达式实现我需要的功能?
最佳答案
发布 my suggestion因为它被证明是有帮助的:
^(.*?[._-]?)(?=[\W_])[._-]?(\()?([a-z]{2,3})(?(2)\)|)(?:[_\W]forced)?$
参见 regex demo .
详情
^
- 字符串的开始(.*?[._-]?)
- 第 1 组:任何 0+ 个字符,换行符除外,尽可能少,然后是可选的。
、_
或-
(?=[\W_])[._-]?(\()?
- 下一个字符必须是非字母数字字符(由于(?= [\W_])
posititve lookahead),然后是可选的.
、-
或_
匹配,然后是可选的(
被捕获到第 2 组中([a-z]{2,3})
- 2 或 3 个小写 ASCII 字母(?(2)\)|)
- 条件构造:如果第 2 组匹配,则匹配)
,否则匹配空字符串(?:[_\W]forced)?
- 可选的非捕获组匹配 1 次或 0 次出现[_\W]
- 任何非字母数字字符forced
- 一个子串
$
- 字符串结尾。
关于c# - 在 C# 中使用正则表达式从字符串中提取带有可选特殊字符的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52880315/