是否有正则表达式来测试字符串是否适用于区域设置

本文关键字:是否 适用于 区域 设置 字符串 测试 正则表达式 | 更新日期: 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}))?$

其中包括:

  1. 语言代码:ISO 639 2 或 3,或 4 供将来使用,alpha。
  2. 可选脚本代码:ISO 15924 4 alpha。
  3. 可选国家/地区代码:ISO 3166-1 2 个字母或 3 位数字。
  4. 用下划线或短划线分隔。

有效的例子是:

  • 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-001en-150ar-001es-419,它们可用于通用语言目的。例如,en-001旨在将en-us作为仿制英语的依赖脱钩,特别是因为它的日期格式和拼写与其他 100 种区域en变体完全不同。en-150区域设置与en-001相同,但编号分隔符和其他特定于欧洲的格式除外。

一般来说,正则表达式是一个很好的前端健全性检查,可以过滤掉非法字符,尤其是为将来可能的添加保留格式。它还有助于防止恶意字符组合发送到查找工具,尤其是在使用基于文本的查找命令机制(如 SQL 或 Xpath(时。

这将针对以下方面测试您的输入:

'.[a-z]{2}-[A-Z]{2}$

这真的是非常字面的:"匹配一个点('.,点是正则表达式中的特殊字符(,后跟从az的任何字符中的两个([a-z]{2} - [...]是一个字符类(,然后是一个破折号(-(,然后是两个从AZ的任何字符([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-goethezh-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

所以正则表达式在语言环境只有两个字符(只有小写(的情况下有效或者它有两个字符(只有小写(+ _ + 两个字符(可以是大写(