正则表达式 - 如果开始匹配则匹配结束
Posted
技术标签:
【中文标题】正则表达式 - 如果开始匹配则匹配结束【英文标题】:Regular Expression - Match End if Start is Match 【发布时间】:2015-07-06 23:15:02 【问题描述】:我要匹配以下字符串:
[anything can be here]
[anything can be here]
我可以只使用一个正则表达式来实现吗?
我目前正在使用这个'^\[()?.+()?]$'
,但它也会匹配:
[anything can be here]
[anything can be here]
只有在使用 时,我才需要匹配
。
请注意,我只能使用正则表达式匹配函数,因为我已将其实现为 SQL CLR
函数,以便在 T-SQL
语句中使用它。
【问题讨论】:
【参考方案1】:基本上你可以写(逐字字符串):
^\[(?:.+|[^]]+)]$
你可以使用更复杂的条件语句(?(condition)then|else)
:
^\[()?[^]]+(?(1)|)]$
(如果捕获组 1 存在,则 否则没有)
但这种方式可能效率较低。
【讨论】:
条件语句中甚至不需要|
,只需^\[()?[^]]+(?(1))]$
就足够了(只有yes部分)。
@stribizhev:确实,这只是为了说明条件结构。但正如我所说,使用这种方式是大材小用,仅供参考。【参考方案2】:
我得到了这个工作:\[[^].*[^]\]|\[\.*\\]
编辑 正如 OP 所指出的,括号之间需要有一些东西,所以“一个或多个”匹配更合适:
\[[^].+[^]\]|\[\.+\\]
see RegEx example here
【讨论】:
【参考方案3】:您的正则表达式 ^\[()?.+()?]$
将仅匹配单个字符串,例如 [...]
或 [...]
,因为 1) 您有锚点 (^$
),并且两个花括号以相同的模式出现。
我建议使用否定的look-behinds 来避免匹配[]
-ed 字符串中只有一个大括号的字符串,如下所示:
var rgx = new Regex(@"((?!\[\[^]+\]|\[[^]+\)\[\?.+?\?\])");
var tst = "[anything can be here] [anything can be here] [anything can be here] [anything can be here]";
var mtch = rgx.Matches(tst).Cast<Match>().ToList();
即使在更大的上下文中,这也将确保您匹配 []
-ed 字符串。
结果:
【讨论】:
【参考方案4】:试试这个:
\[[^].*[^]\]|\[[^]\]|\[\.+\\]
当分解时匹配 3 种类型的字符串:
[]
包围 ≥ 2 个字符,前提是第一个字符不是
,最后一个字符不是
[]
包围任何东西
[]
包围单个非大括号字符(以前的答案未涵盖的边缘情况)
【讨论】:
我认为它不能正常工作。 1)太贪婪,2)匹配不需要的情况。见goo.gl/9dlTyX【参考方案5】:好的,我知道这个问题已经得到解答,但我想我会展示一个纯 T-SQL 解决方案作为替代方案。
DECLARE @yourTable TABLE (val VARCHAR(100));
INSERT INTO @yourTable
VALUES ('[anything can be here]'),
('[anything can be here]'),
('[anything can be here]'),
('[anything can be here]');
WITH CTE_Brackets
AS
(
SELECT val,
CASE
WHEN CHARINDEX('',val) > 0 THEN CHARINDEX('',val)
END AS L_curly,
CASE
WHEN CHARINDEX('',val) > 0 THEN CHARINDEX('',val)
END AS R_curly,
CASE
WHEN CHARINDEX('[',val) > 0 THEN CHARINDEX('[',val)
END AS L_bracket,
CASE
WHEN CHARINDEX(']',val) > 0 THEN CHARINDEX(']',val)
END AS R_bracket
FROM @yourTable
),
CTE_string
AS
(
SELECT val,
L_curly,
R_curly,
L_bracket,
R_bracket,
SUBSTRING(val,start_pos,end_pos - start_pos) val_string
FROM CTE_Brackets A
CROSS APPLY (SELECT COALESCE(L_curly,L_bracket) + 1 AS start_pos,
COALESCE(R_curly,R_bracket) AS end_pos
) CA
)
SELECT A.val,B.val
FROM CTE_string A
INNER JOIN CTE_string B
ON A.val_string = B.val_string
AND
(
(
A.L_curly IS NOT NULL
AND A.R_curly IS NULL
AND B.L_curly IS NULL
AND B.R_curly IS NOT NULL
) --left curly matching right only curly
OR
(
A.L_curly + A.R_curly IS NOT NULL
AND B.R_curly IS NULL
AND B.L_curly IS NULL
) --matches both curly to no curly
)
ORDER BY B.val
【讨论】:
以上是关于正则表达式 - 如果开始匹配则匹配结束的主要内容,如果未能解决你的问题,请参考以下文章