diff --git a/Katheryne.Tests/StringFormatterTests.cs b/Katheryne.Tests/StringFormatterTests.cs new file mode 100644 index 0000000..d9d697d --- /dev/null +++ b/Katheryne.Tests/StringFormatterTests.cs @@ -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)); + } +} \ No newline at end of file diff --git a/Katheryne/KatheryneChatRobot.cs b/Katheryne/KatheryneChatRobot.cs index 94c226e..9537f56 100644 --- a/Katheryne/KatheryneChatRobot.cs +++ b/Katheryne/KatheryneChatRobot.cs @@ -27,7 +27,7 @@ public class KatheryneChatRobot : IChatRobot { return new[] { - _grammarTree[_currentStage].Answer + _grammarTree[_currentStage].Answer.RowString }; } @@ -55,7 +55,17 @@ public class KatheryneChatRobot : IChatRobot if (match.Success) { _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); break; } @@ -81,7 +91,7 @@ public class KatheryneChatRobot : IChatRobot { flag = true; _currentStage = transformer.NextStage; - result.Add(_grammarTree[_currentStage].Answer); + result.Add(_grammarTree[_currentStage].Answer.RowString); _logger.LogInformation("Moving to stage {} with empty transform.", _currentStage); break; diff --git a/Katheryne/Models/FormatTag.cs b/Katheryne/Models/FormatTag.cs new file mode 100644 index 0000000..112ba8e --- /dev/null +++ b/Katheryne/Models/FormatTag.cs @@ -0,0 +1,3 @@ +namespace Katheryne.Models; + +public record FormatTag(string Value, int Index); \ No newline at end of file diff --git a/Katheryne/Models/InnerStage.cs b/Katheryne/Models/InnerStage.cs index 29aec60..4eacdd8 100644 --- a/Katheryne/Models/InnerStage.cs +++ b/Katheryne/Models/InnerStage.cs @@ -6,12 +6,12 @@ internal class InnerStage public List Transformers { get; } = new(); - public string Answer { get; } + public StringFormatter Answer { get; } public InnerStage(Stage stage) { Name = stage.Name; - Answer = stage.Answer; + Answer = new StringFormatter(stage.Answer); foreach (Transformer transformer in stage.Transformers) { diff --git a/Katheryne/Models/StringFormatter.cs b/Katheryne/Models/StringFormatter.cs new file mode 100644 index 0000000..76b7da9 --- /dev/null +++ b/Katheryne/Models/StringFormatter.cs @@ -0,0 +1,78 @@ +using System.Text.RegularExpressions; + +namespace Katheryne.Models; + +/// +/// 格式化字符串模型类 +/// +public class StringFormatter +{ + private readonly string _originString; + private readonly List _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 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))); + } + } +} \ No newline at end of file