C#语音天气应用:如何从固定语句后提取字典匹配的城市键?
Hey William, let's work through this problem together! You're building a voice-activated weather app with that fixed prefix, and need to pull the matching city from your dictionary—totally get it. Here are a couple of straightforward, effective approaches you can implement right away:
Approach 1: String Trimming + Dictionary Lookup
This is the simplest method if you're confident the input strictly follows the "prefix + city name" format. We'll normalize the input to avoid case mismatches, trim off the prefix, then check if the remaining string exists in your dictionary.
// Your existing city dictionary (I'll add sample entries for context) static Dictionary<string, int> cityIds = new Dictionary<string, int> { {"gothenburg", 12345}, {"london", 67890}, {"paris", 11223} }; string userInput = "what is the weather like in gothenburg"; string fixedPrefix = "what is the weather like in"; // Normalize everything to lowercase to handle voice recognition case inconsistencies string lowerInput = userInput.ToLower(); string lowerPrefix = fixedPrefix.ToLower(); if (lowerInput.StartsWith(lowerPrefix)) { // Grab the part after the prefix, then clean up extra spaces string cityCandidate = lowerInput.Substring(lowerPrefix.Length).Trim(); // Check if the city exists in our dictionary if (cityIds.TryGetValue(cityCandidate, out int matchingCityId)) { // Success! Use the city ID to fetch weather data Console.WriteLine($"Found match: {cityCandidate} (ID: {matchingCityId})"); } else { // No matching city in the dictionary Console.WriteLine("Sorry, that city isn't in our database yet."); } } else { // Input doesn't match the expected prefix Console.WriteLine("Hmm, that doesn't sound like a weather request I recognize."); }
Approach 2: Regular Expressions (For More Flexibility)
If you need to handle minor variations in voice input (like extra spaces or trailing words like "today"), regex is a great tool. It lets you explicitly capture the city name portion regardless of small formatting quirks.
using System.Text.RegularExpressions; // Same city dictionary as before static Dictionary<string, int> cityIds = new Dictionary<string, int> { {"gothenburg", 12345}, {"london", 67890}, {"paris", 11223} }; string userInput = "what is the weather like in gothenburg today"; // Regex pattern: matches the prefix, then captures any sequence of letters/spaces as the city string regexPattern = @"^what is the weather like in\s+(?<city>[a-zA-Z\s]+)(?:\s.*)?$"; Match matchResult = Regex.Match(userInput.ToLower(), regexPattern); if (matchResult.Success) { string cityCandidate = matchResult.Groups["city"].Value.Trim(); if (cityIds.TryGetValue(cityCandidate, out int matchingCityId)) { Console.WriteLine($"Found match: {cityCandidate} (ID: {matchingCityId})"); } else { Console.WriteLine("City not found in our database."); } }
Bonus: Make Dictionary Lookup Case-Insensitive
Instead of converting everything to lowercase, you can initialize your dictionary to ignore case from the start. This makes the code cleaner and handles voice recognition's random capitalization automatically:
// Initialize dictionary with case-insensitive comparison static Dictionary<string, int> cityIds = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) { {"Gothenburg", 12345}, {"London", 67890}, {"Paris", 11223} }; // Now you can skip converting input to lowercase—TryGetValue will handle case differences!
All these methods should work smoothly for your use case. Let me know if you run into edge cases (like multi-word city names) and we can tweak the code further!
内容的提问来源于stack exchange,提问作者William

