add: 在用户输入中提取参数
This commit is contained in:
		
							
								
								
									
										37
									
								
								Katheryne.Tests/StringFormatterTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Katheryne.Tests/StringFormatterTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					using Katheryne.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Katheryne.Tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class StringFormatterTests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [Fact]
 | 
				
			||||||
 | 
					    public void FormatTest1()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        StringFormatter formatter = new("Hello $1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Regex regex = new("I'm (.*)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Match match = regex.Match("I'm jackfiled");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Assert.True(match.Success);
 | 
				
			||||||
 | 
					        Assert.True(formatter.IsFormat);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Assert.Equal("Hello jackfiled", formatter.Format(match.Groups));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Fact]
 | 
				
			||||||
 | 
					    public void FormatTest2()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        StringFormatter formatter = new("$你好呀 $1, 欢迎你离开垃圾的$2.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Regex regex = new("你好,我是(.*),我来自(.*)\\.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Match match = regex.Match("你好,我是Ichirinko,我来自Trinity.");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Assert.True(match.Success);
 | 
				
			||||||
 | 
					        Assert.True(formatter.IsFormat);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Assert.Equal("$你好呀 Ichirinko, 欢迎你离开垃圾的Trinity.", formatter.Format(match.Groups));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -27,7 +27,7 @@ public class KatheryneChatRobot : IChatRobot
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return new[]
 | 
					        return new[]
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _grammarTree[_currentStage].Answer
 | 
					            _grammarTree[_currentStage].Answer.RowString
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,7 +55,17 @@ public class KatheryneChatRobot : IChatRobot
 | 
				
			|||||||
            if (match.Success)
 | 
					            if (match.Success)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                _currentStage = transformer.NextStage;
 | 
					                _currentStage = transformer.NextStage;
 | 
				
			||||||
                result.Add(_grammarTree[_currentStage].Answer);
 | 
					                StringFormatter answer = _grammarTree[_currentStage].Answer;
 | 
				
			||||||
 | 
					                if (answer.IsFormat)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    string temp = answer.Format(match.Groups);
 | 
				
			||||||
 | 
					                    _logger.LogInformation("Format answer {} to {}.", answer.RowString, temp);
 | 
				
			||||||
 | 
					                    result.Add(temp);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    result.Add(answer.RowString);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                _logger.LogInformation("Moving to stage {} on input {}.", _currentStage, input);
 | 
					                _logger.LogInformation("Moving to stage {} on input {}.", _currentStage, input);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -81,7 +91,7 @@ public class KatheryneChatRobot : IChatRobot
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    flag = true;
 | 
					                    flag = true;
 | 
				
			||||||
                    _currentStage = transformer.NextStage;
 | 
					                    _currentStage = transformer.NextStage;
 | 
				
			||||||
                    result.Add(_grammarTree[_currentStage].Answer);
 | 
					                    result.Add(_grammarTree[_currentStage].Answer.RowString);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    _logger.LogInformation("Moving to stage {} with empty transform.", _currentStage);
 | 
					                    _logger.LogInformation("Moving to stage {} with empty transform.", _currentStage);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								Katheryne/Models/FormatTag.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Katheryne/Models/FormatTag.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					namespace Katheryne.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public record FormatTag(string Value, int Index);
 | 
				
			||||||
@@ -6,12 +6,12 @@ internal class InnerStage
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public List<InnerTransformer> Transformers { get; } = new();
 | 
					    public List<InnerTransformer> Transformers { get; } = new();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    public string Answer { get; }
 | 
					    public StringFormatter Answer { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public InnerStage(Stage stage)
 | 
					    public InnerStage(Stage stage)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Name = stage.Name;
 | 
					        Name = stage.Name;
 | 
				
			||||||
        Answer = stage.Answer;
 | 
					        Answer = new StringFormatter(stage.Answer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (Transformer transformer in stage.Transformers)
 | 
					        foreach (Transformer transformer in stage.Transformers)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										78
									
								
								Katheryne/Models/StringFormatter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								Katheryne/Models/StringFormatter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Katheryne.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// 格式化字符串模型类
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class StringFormatter
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private readonly string _originString;
 | 
				
			||||||
 | 
					    private readonly List<FormatTag> _formatTags = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public StringFormatter(string originString)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _originString = originString;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        GetFormatTags();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public bool IsFormat => _formatTags.Count != 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string RowString => _originString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string Format(GroupCollection collection)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var result = new string(_originString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (FormatTag tag in _formatTags)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (tag.Index > collection.Count)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            result = result.Replace(tag.Value, collection[tag.Index].Value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void GetFormatTags()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        List<int> indexes = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (var i = 0; i < _originString.Length; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_originString[i] == '$')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                indexes.Add(i);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (int index in indexes)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string value = string.Empty;
 | 
				
			||||||
 | 
					            int pos = index + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 如果 $ 之后的字符不是数字就忽略处理
 | 
				
			||||||
 | 
					            if (_originString[pos] < '0' || _originString[pos] > '9')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while (_originString[pos] >= '0' && _originString[pos] <= '9')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                value = value + _originString[pos];
 | 
				
			||||||
 | 
					                pos++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (pos >= _originString.Length)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            _formatTags.Add(new FormatTag('$' + value, int.Parse(value)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user