使用附加增量(即 NewObject_1)重命名复制的对象
本文关键字:重命名 复制 对象 NewObject | 更新日期: 2023-09-27 18:35:10
我目前正在使用Treeview
控件开发WinForms
应用程序。我添加了一个复制机制来复制当前选定的Treenode
。复制的Treenode
对象的名称应通过以下方式与原始Treenode
不同:"一个节点","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#
中缺乏手语正则表达式的专业知识吗?
编辑以澄清:应确定下一个可用的空白点。稍后删除其中一个节点/名称时,有一个空位。因此,如果只有字符串"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的苗条方法可能就足够了。
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();
}
}
}