Last active
December 4, 2025 09:46
-
-
Save cnbluefire/10b7d84c69536fd80a90bac72a867c06 to your computer and use it in GitHub Desktop.
猜成语小玩具
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Text.Json; | |
| var data = LoadIdioms(); | |
| Console.WriteLine(""" | |
| 使用空格分割四字的个匹配,支持以下模式: | |
| 汉字:精确匹配 | |
| 字母:模糊匹配拼音 | |
| 字母+感叹号:精确匹配拼音 | |
| 数字:音调,可以追加到字母后面,如sheng!1 | |
| 下划线:忽略 | |
| 例如: | |
| >>> yi sheng!1 1 _ | |
| 一生一代 | |
| 一生一世 | |
| 英声欺人 | |
| 蝇声蛙躁 | |
| 成语数据库来自 | |
| https://github.com/crazywhalecc/idiom-database/raw/refs/heads/master/data/idiom.json | |
| 如果无法自动下载,可以手动下载后放置到 %TEMP%\FrogDataFolder\idiom.json | |
| """); | |
| while (true) | |
| { | |
| Console.WriteLine("请输入以空格分隔的四个字或拼音:"); | |
| var line = Console.ReadLine(); | |
| var arr = line?.Split(' ') ?? []; | |
| if (arr.Length == 4) | |
| { | |
| var query = data; | |
| for (int i = 0; i < arr.Length; i++) | |
| { | |
| if (TryParseData(arr[i], out var alpha, out var fullMatchAlpha, out var tone, out var text)) | |
| { | |
| var idx = i; | |
| if (!string.IsNullOrEmpty(alpha)) | |
| { | |
| query = query.Where(c => c.Pinyin_r_Array[idx].Contains(alpha)); | |
| } | |
| if (!string.IsNullOrEmpty(fullMatchAlpha)) | |
| { | |
| query = query.Where(c => c.Pinyin_r_Array[idx] == fullMatchAlpha); | |
| } | |
| if (tone.HasValue) | |
| { | |
| query = query.Where(c => c.ToneArray[idx] == tone.Value); | |
| } | |
| if (!string.IsNullOrEmpty(text)) | |
| { | |
| query = query.Where(c => c.Word![idx] == text[0]); | |
| } | |
| } | |
| } | |
| foreach (var item in query) | |
| { | |
| Console.WriteLine($"{item.Word}"); | |
| } | |
| } | |
| } | |
| static bool TryParseData(string input, out string? alpha, out string? fullMatchAlpha, out int? tone, out string? text) | |
| { | |
| alpha = null; | |
| fullMatchAlpha = null; | |
| tone = null; | |
| text = null; | |
| if (string.IsNullOrEmpty(input)) return false; | |
| if (input == "" || input == "_" || input == "?" || input == ".") return false; | |
| bool fullMatch = input.Contains('!'); | |
| input = input.Replace("!", ""); | |
| if (char.IsNumber(input[^1])) | |
| { | |
| tone = input[^1] - '0'; | |
| input = input[..^1]; | |
| } | |
| if (input.Length > 0) | |
| { | |
| if (char.IsAsciiLetter(input[0])) | |
| { | |
| if (fullMatch) fullMatchAlpha = input; | |
| else alpha = input; | |
| } | |
| else | |
| { | |
| text = input; | |
| } | |
| } | |
| return true; | |
| } | |
| static IEnumerable<IdiomModel> LoadIdioms() | |
| { | |
| var tmpPath = System.IO.Path.Combine(Path.GetTempPath(), "FrogDataFolder"); | |
| if (!Directory.Exists(tmpPath)) Directory.CreateDirectory(tmpPath); | |
| var jsonPath = Path.Combine(tmpPath, "idiom.json"); | |
| if (!File.Exists(jsonPath)) | |
| { | |
| using var httpClient = new HttpClient(); | |
| using var stream = httpClient.GetStreamAsync("https://github.com/crazywhalecc/idiom-database/raw/refs/heads/master/data/idiom.json").GetAwaiter().GetResult(); | |
| using var fs = File.Create(jsonPath); | |
| stream.CopyTo(fs); | |
| } | |
| return JsonSerializer.Deserialize<IdiomModel[]>(File.ReadAllText(jsonPath), JsonSerializerOptions.Web)? | |
| .Where(c => c.Word is { Length: 4 } && c.Abbreviation is { Length: 4 }) ?? throw new ArgumentException(); | |
| } | |
| public class IdiomModel | |
| { | |
| public string? Derivation { get; set; } | |
| public string? Example { get; set; } | |
| public string? Explanation { get; set; } | |
| public string? Pinyin { get; set; } | |
| public string? Word { get; set; } | |
| public string? Abbreviation { get; set; } | |
| public string? Pinyin_r { get; set; } | |
| public string? First { get; set; } | |
| public string? Last { get; set; } | |
| private string[]? pinyin_data; | |
| private string[]? pinyin_r_data; | |
| private int[]? tone_data; | |
| public string[] PinyinArray => pinyin_data ??= Pinyin?.Split(' ') ?? []; | |
| public string[] Pinyin_r_Array => pinyin_r_data ??= Pinyin_r?.Split(' ') ?? []; | |
| public int[] ToneArray => tone_data ??= PinyinArray.Select(c => ToTone(c)).ToArray(); | |
| private static int ToTone(string text) | |
| { | |
| const string Tone1 = "āēīōūǖ"; | |
| const string Tone2 = "áéíóúǘń"; | |
| const string Tone3 = "ǎěǐǒǔǚň"; | |
| const string Tone4 = "àèìòùǜ"; | |
| if (text.Any(c => Tone1.Contains(c))) return 1; | |
| if (text.Any(c => Tone2.Contains(c))) return 2; | |
| if (text.Any(c => Tone3.Contains(c))) return 3; | |
| if (text.Any(c => Tone4.Contains(c))) return 4; | |
| return 0; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment