在Java中,有所谓的方法isJavaIdentifierStart和isJavaIdentifierPart对可用于判断一个字符串是一个有效的Java标识,像这样的字符类别:
public boolean isJavaIdentifier(String s) {
int n = s.length();
if (n==0) return false;
if (!Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < n; i++)
if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
C#有这样的东西吗?
Mar*_*ers 34
是:
// using System.CodeDom.Compiler;
CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
if (provider.IsValidIdentifier (YOUR_VARIABLE_NAME)) {
// Valid
} else {
// Not valid
}
Run Code Online (Sandbox Code Playgroud)
我会对这里提供的其他解决方案保持警惕.调用CodeDomProvider.CreateProvider需要查找和解析Machine.Config文件以及app.config文件.这可能比检查你自己的弦所需的时间慢几倍.
相反,我会主张你做出以下改变之一:
将提供程序缓存在静态变量中.
这将使您仅创建一次创建它,但它会减慢类型加载速度.
通过创建自己的Microsoft.CSharp.CSharpCodeProvider实例直接创建提供程序
这将跳过配置文件一起解析.
编写代码来实现检查你自己.
如果这样做,您可以最大程度地控制其实施方式,如果需要,可以帮助您优化性能.有关C#标识符的完整词法语法,请参阅C#语言规范的 2.2.4节.
基本上是这样的:
const string start = @"(\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl})";
const string extend = @"(\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf})";
Regex ident = new Regex(string.Format("{0}({0}|{1})*", start, extend));
s = s.Normalize();
return ident.IsMatch(s);
Run Code Online (Sandbox Code Playgroud)
小智 6
由于Roslyn是开源的,代码分析工具就在您的指尖,它们是为性能而编写的。(现在它们处于预发布阶段)。
但是,我无法谈论加载程序集的性能成本。
使用 nuget 安装工具:
Install-Package Microsoft.CodeAnalysis -Pre
Run Code Online (Sandbox Code Playgroud)
问你的问题:
var isValid = Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsValidIdentifier("I'mNotValid");
Console.WriteLine(isValid); // False
Run Code Online (Sandbox Code Playgroud)
死灵法术在这里。
在 .NET Core/DNX 中,你可以使用 Roslyn-SyntaxFacts
Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsReservedKeyword(
Microsoft.CodeAnalysis.CSharp.SyntaxFacts.GetKeywordKind("protected")
);
foreach (ColumnDefinition cl in tableColumns)
{
sb.Append(@" public ");
sb.Append(cl.DOTNET_TYPE);
sb.Append(" ");
// for keywords
//if (!Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsValidIdentifier(cl.COLUMN_NAME))
if (Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsReservedKeyword(
Microsoft.CodeAnalysis.CSharp.SyntaxFacts.GetKeywordKind(cl.COLUMN_NAME)
))
sb.Append("@");
sb.Append(cl.COLUMN_NAME);
sb.Append("; // ");
sb.AppendLine(cl.SQL_TYPE);
} // Next cl
Run Code Online (Sandbox Code Playgroud)
或者在 Codedom 的旧变体中 - 在查看 mono 源代码后:
CodeDomProvider.cs
public virtual bool IsValidIdentifier (string value)
286 {
287 ICodeGenerator cg = CreateGenerator ();
288 if (cg == null)
289 throw GetNotImplemented ();
290 return cg.IsValidIdentifier (value);
291 }
292
Run Code Online (Sandbox Code Playgroud)
然后 CSharpCodeProvider.cs
public override ICodeGenerator CreateGenerator()
91 {
92 #if NET_2_0
93 if (providerOptions != null && providerOptions.Count > 0)
94 return new Mono.CSharp.CSharpCodeGenerator (providerOptions);
95 #endif
96 return new Mono.CSharp.CSharpCodeGenerator();
97 }
Run Code Online (Sandbox Code Playgroud)
然后 CSharpCodeGenerator.cs
protected override bool IsValidIdentifier (string identifier)
{
if (identifier == null || identifier.Length == 0)
return false;
if (keywordsTable == null)
FillKeywordTable ();
if (keywordsTable.Contains (identifier))
return false;
if (!is_identifier_start_character (identifier [0]))
return false;
for (int i = 1; i < identifier.Length; i ++)
if (! is_identifier_part_character (identifier [i]))
return false;
return true;
}
private static System.Collections.Hashtable keywordsTable;
private static string[] keywords = new string[] {
"abstract","event","new","struct","as","explicit","null","switch","base","extern",
"this","false","operator","throw","break","finally","out","true",
"fixed","override","try","case","params","typeof","catch","for",
"private","foreach","protected","checked","goto","public",
"unchecked","class","if","readonly","unsafe","const","implicit","ref",
"continue","in","return","using","virtual","default",
"interface","sealed","volatile","delegate","internal","do","is",
"sizeof","while","lock","stackalloc","else","static","enum",
"namespace",
"object","bool","byte","float","uint","char","ulong","ushort",
"decimal","int","sbyte","short","double","long","string","void",
"partial", "yield", "where"
};
static void FillKeywordTable ()
{
lock (keywords) {
if (keywordsTable == null) {
keywordsTable = new Hashtable ();
foreach (string keyword in keywords) {
keywordsTable.Add (keyword, keyword);
}
}
}
}
static bool is_identifier_start_character (char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '@' || Char.IsLetter (c);
}
static bool is_identifier_part_character (char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || Char.IsLetter (c);
}
Run Code Online (Sandbox Code Playgroud)
你得到这个代码:
public static bool IsValidIdentifier (string identifier)
{
if (identifier == null || identifier.Length == 0)
return false;
if (keywordsTable == null)
FillKeywordTable();
if (keywordsTable.Contains(identifier))
return false;
if (!is_identifier_start_character(identifier[0]))
return false;
for (int i = 1; i < identifier.Length; i++)
if (!is_identifier_part_character(identifier[i]))
return false;
return true;
}
internal static bool is_identifier_start_character(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '@' || char.IsLetter(c);
}
internal static bool is_identifier_part_character(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || char.IsLetter(c);
}
private static System.Collections.Hashtable keywordsTable;
private static string[] keywords = new string[] {
"abstract","event","new","struct","as","explicit","null","switch","base","extern",
"this","false","operator","throw","break","finally","out","true",
"fixed","override","try","case","params","typeof","catch","for",
"private","foreach","protected","checked","goto","public",
"unchecked","class","if","readonly","unsafe","const","implicit","ref",
"continue","in","return","using","virtual","default",
"interface","sealed","volatile","delegate","internal","do","is",
"sizeof","while","lock","stackalloc","else","static","enum",
"namespace",
"object","bool","byte","float","uint","char","ulong","ushort",
"decimal","int","sbyte","short","double","long","string","void",
"partial", "yield", "where"
};
internal static void FillKeywordTable()
{
lock (keywords)
{
if (keywordsTable == null)
{
keywordsTable = new System.Collections.Hashtable();
foreach (string keyword in keywords)
{
keywordsTable.Add(keyword, keyword);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12065 次 |
| 最近记录: |