如何基于正则表达式从输入String数组生成指定格式的元组数组
Got it, let's fix this regex issue and get your conversion working properly in Scala! Here's a complete, polished solution tailored to your needs:
First, let's refine the regex patterns you started with—they were missing closing brackets and needed tweaks to handle whitespace and name spacing correctly. We'll use Scala's pattern matching to cleanly handle both entries with a country and those without.
Step 1: Define Robust Regex Patterns
We need two patterns to cover all cases:
For entries with a country: Captures the full name, country (inside parentheses), and date, accounting for optional whitespace around the parentheses.
val withCountryPattern = "^(.+?)\\s*\\((.+)\\)\\s*(.+)$".rBreakdown:
^(.+?): Non-greedy match for the name (stops at the first whitespace before parentheses, so it captures full names like "Brian McNamee" correctly)\\s*: Matches any number of spaces (including zero) before/after the parentheses\\((.+)\\): Captures the country text inside the parentheses(.+)$: Captures the remaining text as the date
For entries without a country: Explicitly matches the name and date format to avoid splitting names that might contain numbers.
val withoutCountryPattern = "^(.+?)\\s+((?:\\d{1,2})(?:st|nd|rd|th)\\s+\\w+\\s+\\d{4})$".rBreakdown:
^(.+?): Non-greedy match for the name\\s+: Matches one or more spaces separating the name from the date((?:\\d{1,2})(?:st|nd|rd|th)\\s+\\w+\\s+\\d{4}): Targets date formats like "18th September 2009" to avoid edge cases
Step 2: Build the Parsing Function
Create a helper function that converts each string entry to your desired tuple using pattern matching:
def parseUserEntry(entry: String): (String, String, String) = entry match { case withCountryPattern(name, country, date) => (name.trim, country.trim, date.trim) case withoutCountryPattern(name, date) => (name.trim, "", date.trim) case _ => ("", "", "") // Handle invalid entries if needed (adjust as per your use case) }
Step 3: Test the Implementation
Apply the function to your input array to get the expected result:
val userInfo = Array( "Brian McNamee (Canada) 16th October 2015", "Claudia Stanzani 18th September 2009", "Maria Garcia (Mexico) 3rd July 2012", "Robert Lee 10th April 2017" ) val parsedTuples = userInfo.map(parseUserEntry) // Output: Array(("Brian McNamee", "Canada", "16th October 2015"), ("Claudia Stanzani", "", "18th September 2009"), ...)
Quick Tips
- The non-greedy
+?is critical here—it prevents the name match from swallowing up whitespace before the parentheses. - Using
trim()cleans up any accidental extra spaces captured by the regex. - If your input has more varied date formats, you can adjust the date part of the
withoutCountryPatternto match those variations.
内容的提问来源于stack exchange,提问作者jOasis

