重命名带有附加增量的复制对象(即 NewObject_1)
Rename copied objects with attached increment (i.e. NewObject_1)
我目前正在开发一个使用 Treeview
控件的 WinForms
应用程序。我添加了一个复制机制来复制当前选择的 Treenode
。
复制的 Treenode
对象的名称应该与原始的 Treenode
不同,方式如下:
"aNode",
"aNode_1",
"aNode_2".
感觉Regex
是要走的路。
这是我目前得到的:
string theNameToBe = "aName";
List<string> theAlreadyInUseNames // Filled beforehand
int i = 1;
do
{
// ToDo: Use Regex to get XXXXX_1 -> XXXXX_2 as a possible name instead of XXXXX_1_1
Regex aPossibleNewNameRegex = new Regex( String.Format("^{0}[_]\d+$", theNameToBe),RegexOptions.IgnoreCase);
// This does not take a previously created XXXXX_1 into account and continues to attach "_1"s to the string
string thePossibleNewName = String.Format( theNameToBe + "_{0}", i );
if ( !theAlreadyInUseNames.Any( s => s.Equals( thePossibleNewName, StringComparison.OrdinalIgnoreCase ) ) )
{
theNextAvailableName = thePossibleNewName;
break;
}
i++;
} while ( i < int.MaxValue );
这只会获取后续名称,例如 "aNode"、"aNode_1"、"aNode_1_1"、...等等。
你能帮我解决我在 C#
中处理正则表达式方面缺乏专业知识的问题吗?
编辑澄清:
应确定下一个可用的空位。当稍后删除其中一个 Nodes/Names 时,就会有一个空位。因此,如果仅存在字符串 "aName"、"aName_1" 和 "aName_3",则 "aName_2" 是正确的发现。
可以像
一样简单
var selected = "node_3";
var names = new[] { "node_1", "node_3" };
var prefix = selected.Substring(0, selected.IndexOf('_') + 1);
var number = 1;
string name; // result
do
name = prefix + number++;
while (names.Contains(name));
我可能已经找到了满足要求的解决方案。这是初稿,可能会在经过一轮单元测试和现实生活场景后进行更新。
而且总是有可能这个版本对于工作来说太复杂了,而 Sinatrs slim 方法可能就足够了。
static void Main( string[] args )
{
List<string> theAlreadyInUseNames = new List<string>();
theAlreadyInUseNames.Add( "aName" );
theAlreadyInUseNames.Add( "aName_1" );
theAlreadyInUseNames.Add( "aName_2" );
theAlreadyInUseNames.Add( "aName_3" );
theAlreadyInUseNames.Add( "aName_4" );
theAlreadyInUseNames.Add( "aName_5" );
theAlreadyInUseNames.Add( "aName_7" );
theAlreadyInUseNames.Add( "aName_2_1" );
theAlreadyInUseNames.Add( "aName_2_3" );
string theNameToBe0 = "aName";
string theNameToBe1 = "aName_2";
string theNameToBe2 = "aName_2_1";
List<string> namesToBe = new List<string>();
namesToBe.Add( theNameToBe0 );
namesToBe.Add( theNameToBe1 );
namesToBe.Add( theNameToBe2 );
string[] splits;
char[] charSeparators = new char[] { '_' };
string theNewNameToBe1 = string.Empty;
string theNextAvailableName = String.Empty;
foreach ( var item in namesToBe )
{
splits = item.Split( charSeparators, StringSplitOptions.RemoveEmptyEntries );
if ( splits.Length > 1 )
{
int theNumber = Convert.ToInt32( splits.Last() );
theNewNameToBe1 = splits.ElementAt( 0 );
for ( int i = 1; i < splits.Length - 1; i++ )
{
theNewNameToBe1 = theNewNameToBe1 + "_" + splits.ElementAt( i );
}
int counter = 1;
string theActualNewName = string.Empty;
do
{
theActualNewName = theNewNameToBe1 + "_" + ( theNumber + counter );
if ( !theAlreadyInUseNames.Any( s => s.Equals( theActualNewName, StringComparison.OrdinalIgnoreCase ) ) )
{
theNextAvailableName = theActualNewName;
break;
}
counter++;
} while ( counter < int.MaxValue );
}
else if ( splits.Length == 1 )
{
int counter = 1;
string theActualNewName = string.Empty;
do
{
theActualNewName = theNameToBe + "_" + ( counter );
if ( !theAlreadyInUseNames.Any( s => s.Equals( theActualNewName, StringComparison.OrdinalIgnoreCase ) ) )
{
theNextAvailableName = theActualNewName;
break;
}
counter++;
} while ( counter < int.MaxValue );
}
else
{
throw new ArgumentException();
}
}
}
我目前正在开发一个使用 Treeview
控件的 WinForms
应用程序。我添加了一个复制机制来复制当前选择的 Treenode
。
复制的 Treenode
对象的名称应该与原始的 Treenode
不同,方式如下:
"aNode",
"aNode_1",
"aNode_2".
感觉Regex
是要走的路。
这是我目前得到的:
string theNameToBe = "aName";
List<string> theAlreadyInUseNames // Filled beforehand
int i = 1;
do
{
// ToDo: Use Regex to get XXXXX_1 -> XXXXX_2 as a possible name instead of XXXXX_1_1
Regex aPossibleNewNameRegex = new Regex( String.Format("^{0}[_]\d+$", theNameToBe),RegexOptions.IgnoreCase);
// This does not take a previously created XXXXX_1 into account and continues to attach "_1"s to the string
string thePossibleNewName = String.Format( theNameToBe + "_{0}", i );
if ( !theAlreadyInUseNames.Any( s => s.Equals( thePossibleNewName, StringComparison.OrdinalIgnoreCase ) ) )
{
theNextAvailableName = thePossibleNewName;
break;
}
i++;
} while ( i < int.MaxValue );
这只会获取后续名称,例如 "aNode"、"aNode_1"、"aNode_1_1"、...等等。
你能帮我解决我在 C#
中处理正则表达式方面缺乏专业知识的问题吗?
编辑澄清: 应确定下一个可用的空位。当稍后删除其中一个 Nodes/Names 时,就会有一个空位。因此,如果仅存在字符串 "aName"、"aName_1" 和 "aName_3",则 "aName_2" 是正确的发现。
可以像
一样简单var selected = "node_3";
var names = new[] { "node_1", "node_3" };
var prefix = selected.Substring(0, selected.IndexOf('_') + 1);
var number = 1;
string name; // result
do
name = prefix + number++;
while (names.Contains(name));
我可能已经找到了满足要求的解决方案。这是初稿,可能会在经过一轮单元测试和现实生活场景后进行更新。 而且总是有可能这个版本对于工作来说太复杂了,而 Sinatrs slim 方法可能就足够了。
static void Main( string[] args )
{
List<string> theAlreadyInUseNames = new List<string>();
theAlreadyInUseNames.Add( "aName" );
theAlreadyInUseNames.Add( "aName_1" );
theAlreadyInUseNames.Add( "aName_2" );
theAlreadyInUseNames.Add( "aName_3" );
theAlreadyInUseNames.Add( "aName_4" );
theAlreadyInUseNames.Add( "aName_5" );
theAlreadyInUseNames.Add( "aName_7" );
theAlreadyInUseNames.Add( "aName_2_1" );
theAlreadyInUseNames.Add( "aName_2_3" );
string theNameToBe0 = "aName";
string theNameToBe1 = "aName_2";
string theNameToBe2 = "aName_2_1";
List<string> namesToBe = new List<string>();
namesToBe.Add( theNameToBe0 );
namesToBe.Add( theNameToBe1 );
namesToBe.Add( theNameToBe2 );
string[] splits;
char[] charSeparators = new char[] { '_' };
string theNewNameToBe1 = string.Empty;
string theNextAvailableName = String.Empty;
foreach ( var item in namesToBe )
{
splits = item.Split( charSeparators, StringSplitOptions.RemoveEmptyEntries );
if ( splits.Length > 1 )
{
int theNumber = Convert.ToInt32( splits.Last() );
theNewNameToBe1 = splits.ElementAt( 0 );
for ( int i = 1; i < splits.Length - 1; i++ )
{
theNewNameToBe1 = theNewNameToBe1 + "_" + splits.ElementAt( i );
}
int counter = 1;
string theActualNewName = string.Empty;
do
{
theActualNewName = theNewNameToBe1 + "_" + ( theNumber + counter );
if ( !theAlreadyInUseNames.Any( s => s.Equals( theActualNewName, StringComparison.OrdinalIgnoreCase ) ) )
{
theNextAvailableName = theActualNewName;
break;
}
counter++;
} while ( counter < int.MaxValue );
}
else if ( splits.Length == 1 )
{
int counter = 1;
string theActualNewName = string.Empty;
do
{
theActualNewName = theNameToBe + "_" + ( counter );
if ( !theAlreadyInUseNames.Any( s => s.Equals( theActualNewName, StringComparison.OrdinalIgnoreCase ) ) )
{
theNextAvailableName = theActualNewName;
break;
}
counter++;
} while ( counter < int.MaxValue );
}
else
{
throw new ArgumentException();
}
}
}