是否有正则表达式来测试字符串是否适用于区域设置
本文关键字:是否 适用于 区域 设置 字符串 测试 正则表达式 | 更新日期: 2023-09-27 18:19:41
我对正则表达式一无所知,但我想我必须用它来解决我的问题,我得到了一些文件名,如下所示:
MyResource
MyResource.en-GB
MyResource.en-US
MyResource.fr-FR
MyResource.de-DE
这个想法是测试我的字符串是否以">
[字母][字母]-[字母][字母]"结尾我知道这是一个非常菜鸟,但我只是不知道该怎么做,即使我确切地知道我想做什么...... :(
为了迎合基本变体:
^[A-Za-z]{2,4}([_-][A-Za-z]{4})?([_-]([A-Za-z]{2}|[0-9]{3}))?$
其中包括:
- 语言代码:ISO 639 2 或 3,或 4 供将来使用,alpha。
- 可选脚本代码:ISO 15924 4 alpha。
- 可选国家/地区代码:ISO 3166-1 2 个字母或 3 位数字。
- 用下划线或短划线分隔。
有效的例子是:
- 德
- en-US
- zh-汉特-TW
- 恩非
- aZ_cYrl-aZ.
对于 OP 的特定问题,这需要以 /^MyResource[.]
为前缀,并以 $/
为后缀,以确保整个文件名适用于以区域设置结尾的有效资源文件。
请注意,某些编程语言的函数可能只接受特定形式,例如仅接受下划线和大写国家/地区代码。PHP 的 intl
函数接受大小写和分隔符。PayPal仅接受语言或la_CY
形式,其中la
是语言,CY
是国家/地区。PHP locale_canonicalize
函数可用于标准化为这种格式。
IETF RFC 5646管理这些标签的互联网使用,建议使用大写和分隔格式,如az-Cyrl-AZ
,如上面的前三个示例,尽管它说处理器应该接受任何大小写和分隔符的组合,如最后两个示例。显示区域设置时,使用 -
作为分隔符允许更细粒度的换行,否则可能会像使用 non=wrapping _
时那样产生明显空白的行,尤其是在表格单元格中。
推荐的基本格式的正则表达式为:
^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$
正则表达式仅涵盖基本格式。有额外的变体,如本地区域。RFC 5646 允许此类变体,以及私有扩展和向后兼容形式。这完全取决于所需的粒度。由PHP的intl
函数和其他程序使用的CLDR Unicode数据库可能包含不同版本的此类变体,尽管它们也可能在以后消失。
如果使用基于 CLDR 的函数集(如 PHP 的 intl
扩展(,则可以使用以下函数检查intl
数据库中是否存在语言环境:
<?php
function is_locale($locale=''){
// STANDARDISE INPUT
$locale=locale_canonicalize($locale);
// LOAD ARRAY WITH LOCALES
$locales=resourcebundle_locales('');
// RETURN WHETHER FOUND
return (array_search($locale,$locales)!==F);
}
?>
加载和搜索数据大约需要半毫秒,因此不会对性能造成太大影响。
当然,它只会在与所使用的 PHP 版本一起提供的 CLDR 版本的数据库中找到那些,但会随着每个后续 PHP 版本而更新。
请注意,某些区域设置不是针对国家/地区,而是针对区域,这些区域设置通常是数字,例如001
表示"世界",150
表示"欧洲",419
表示"拉丁美洲"。所以现在有en-001
、en-150
、ar-001
和es-419
,它们可用于通用语言目的。例如,en-001
旨在将en-us
作为仿制英语的依赖脱钩,特别是因为它的日期格式和拼写与其他 100 种区域en
变体完全不同。en-150
区域设置与en-001
相同,但编号分隔符和其他特定于欧洲的格式除外。
一般来说,正则表达式是一个很好的前端健全性检查,可以过滤掉非法字符,尤其是为将来可能的添加保留格式。它还有助于防止恶意字符组合发送到查找工具,尤其是在使用基于文本的查找命令机制(如 SQL 或 Xpath(时。
这将针对以下方面测试您的输入:
'.[a-z]{2}-[A-Z]{2}$
这真的是非常字面的:"匹配一个点('.
,点是正则表达式中的特殊字符(,后跟从a
到z
的任何字符中的两个([a-z]{2}
- [...]
是一个字符类(,然后是一个破折号(-
(,然后是两个从A
到Z
的任何字符([A-Z]{2}
(, 后跟输入结束 ( $
(。
http://www.dotnetperls.com/regex-match <-- 如何在 C# 中对输入应用此正则表达式。这意味着代码看起来像(未经测试(:
// Post edit: this will really return a boolean
if (Regex.Match(input, @"'.[a-z]{2}-[A-Z]{2}$").Success) {
// there is a match
}
http://regex.info <-买那个读一读,它是宇宙中正则表达式的最佳资源
http://regular-expressions.info <--第二好的资源
与其使用正则表达式,我建议你使用 .Net 中对区域性的内置支持,即 System.Globalization.CultureInfo 类;构造函数识别有效的区域性字符串,并为您提供一个可用于区域性特定操作的对象:
try
{
string fileName = "MyResource.en-GB";
string cultureName = System.IO.Path.GetExtension(fileName).TrimStart('.');
CultureInfo cultureInfo = new CultureInfo(cultureName);
}
catch (ArgumentException)
{
// Invalid culture.
}
你可以尝试这样的事情:
[a-z]{2}-[a-z]{2}
你几乎在问题中回答了它。 尝试:
// This basically grabs the locale.
string x = MyResource.whatever.... //Whatever it might be.
string locale = x.SubString(x.Length - 5) // Assuming the locale is 5 characters long.
// Now you have a 'locale' that is ready for comparisons.
if (locale == "en-GB") { .... }
if (locale == "fr-FR") { .... }
etc....
同样,这里有一个有用的两个字母国家/地区代码列表。
http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
我知道这不是真正的正则表达式,但您似乎不确定是否需要绝对使用它。
cultures = CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures);
cultures.Where(o => filename.EndsWith(o.Name));
这可能不是这个问题的答案,但人们可能会路过并正在寻找这个答案。
要匹配 en_GB
等区域设置,您可以使用以下表达式:
/^[a-z]{2}_[A-Z]{2}$/
我将尝试在这里解释它:
^[a-z]
表示以小写字母开头,{2}
表示您期望其中的 2
跟随_
[A-Z]{2}$
表示以大写字母结尾并恰好匹配其中的 2 个,$
表示这些字母必须位于字符串的末尾。
Patanjali 伟大答案的扩展,但也包括命名组和对 RFC 4647 中定义的私有使用的支持。例如:de-DE-x-goethe
或zh-Hant-CN-x-private1-private2
。
^(?<language>[A-Za-z]{2,4})([_-](?<script>[A-Za-z]{4}|[0-9]{3}))?([_-](?<country>[A-Za-z]{2}|[0-9]{3}))?([_-]x[_-](?<private>[A-Za-z0-9-_]+))?$
^[a-z]{2}([_])?([A-Za-z]{2})?$
我使用了这个正则表达式,它仅适用于具有可选"_"的区域设置例如:
en,
德
en_us,
en_US
所以正则表达式在语言环境只有两个字符(只有小写(的情况下有效或者它有两个字符(只有小写(+ _ + 两个字符(可以是大写(