我尝试将以下字符串分成3部分:
Esmael20170101one => Esmael 20170101 one
有哪些选择?
答案 0 :(得分:6)
我建议匹配而不是拆分:
Regex.Split
如果你坚持 string[] items = Regex.Split(source, "([0-9]+)");
string name = items[0];
string code = items[1];
string suffix = items[2];
:
--example calendar table load script
CREATE TABLE dbo.Calendar(
CalendarDate date NOT NULL
CONSTRAINT PK_Calendar PRIMARY KEY
);
WITH
t4 AS (SELECT n FROM (VALUES(0),(0),(0),(0)) t(n))
,t256 AS (SELECT 0 AS n FROM t4 AS a CROSS JOIN t4 AS b CROSS JOIN t4 AS c CROSS JOIN t4 AS d)
,t64k AS (SELECT ROW_NUMBER() OVER (ORDER BY (a.n)) AS num FROM t256 AS a CROSS JOIN t256 AS b)
INSERT INTO dbo.Calendar WITH(TABLOCKX)
SELECT DATEADD(day, num, '20000101')
FROM t64k
WHERE DATEADD(day, num, '20000101') < '20400101'
GO
DECLARE @example TABLE(
DATE_FROM date NOT NULL
,DATE_TO date NULL
);
GO
--example query
INSERT INTO @example VALUES
('2010-05-17', '2010-05-19')
, ('2017-01-02', '2017-01-04')
, ('2017-05-01', NULL)
, ('2017-06-12', NULL)
SELECT
c.CalendarDate
FROM @example AS e
JOIN dbo.Calendar AS c ON
c.CalendarDate BETWEEN e.DATE_FROM AND COALESCE(e.DATE_TO, e.DATE_FROM);
答案 1 :(得分:2)
要使用的正则表达式是([a-zA-Z]*)(\d+)([a-zA-Z]*)
string input = "Esmael20170101one";
var match = new Regex("([a-zA-Z]*)(\\d+)([a-zA-Z]*)").Match(input);
if (match.Success) {
Console.WriteLine(match.Groups[1].ToString());
Console.WriteLine(match.Groups[2].ToString());
Console.WriteLine(match.Groups[3].ToString());
}
Console.Read();
答案 2 :(得分:1)
如果使用正则表达式,则可以定义要捕获的区域。例如,看起来中间组件是日期,所以为什么不指定日期模式是什么,例如
^ # Beginning of String
(?<Name>[^\d]+) # Capture to `Name`
(?<Date>\d{8}) # Capture to `Date`
(?<Note>.+) # Capture to `Note`
$ # End of string
因为我已对此进行了评论,所以您需要使用IgnorePatternWhitespace
的仅模式选项,它只是告诉解析器去除注释(#
)。
结果将是一场比赛
Group[0]
完整匹配。Group["Name"]
或Group[1]
是找到的名称。Group["Date"]
或Group[2]
是找到的日期。Group["Note"]
或Group[3]
是找到的备注。正如德米特里指出的,我们需要更多信息。如果根据其位置在任一组中找到数字,则所有这些模式都可能失败。如果您知道所有日期都在21世纪内,请将我的模式调整为(?<Date>20\d{6})
,以确保在该字段中捕获真实日期;虽然它不是万无一失的。