匹配字符串中第一次出现的分号,只有前缀为' - '

时间:2014-07-21 14:50:30

标签: java regex

我正在尝试为Java编写一个正则表达式,如果有一个分号没有两个(或更多)前导' - '字符,则会匹配。

我只能做相反的工作:一个至少有两个前导' - '字符的分号。

([\-]{2,}.*?;.*)

但我需要像

这样的东西
([^([\-]{2,})])*?;.*

我不知道怎么说不能表达'至少两个字符'。

以下是我需要用表达式评估的一些示例:

; -- a           : should match
-- a ;           : should not match
-- ;             : should not match
--;              : should not match
-;-              : should match
---;             : should not match
-- semicolon ;   : should not match
bla ; bla        : should match
bla              : should not match (; is mandatory)
-;--;            : should match (the first occuring semicolon must not have two or more consecutive leading '-')

5 个答案:

答案 0 :(得分:2)

这个正则表达式似乎符合您的要求

String regex = "[^-]*(-[^-]+)*-?;.*";

DEMO

说明:matches将接受以下字符串:

  • [^-]*可以以非短划线字符开头
  • (-[^-]+)*-?;有点棘手,因为在我们匹配;之前,我们需要确保每个-之后没有其他-
    • (-[^-]+)*每个-后面至少有一个非-个字符
    • -?-位于;
    • 之前
  • ;.*如果早期条件得到满足,我们可以接受;以及之后的任何.*个字符。

更易读的版本,但可能稍微慢一些

((?!--)[^;])*;.*

说明:

为了确保字符串中有;,我们可以在匹配中使用.*;.* 但我们需要在第一个;之前为角色添加一些条件。

所以为了确保匹配的;是第一个,我们可以写这样的正则表达式

[^;]*;.*

表示:

  • [^;]*零个或多个非分号字符
  • ;第一个分号
  • .*零个或多个字符(实际上.无法匹配行分隔符,例如\n\r

所以现在我们需要做的就是确保[^;]匹配的字符不属于--。为此,我们可以使用look-around机制,例如:

    在匹配(?!--)[^;] [^;]之前
  • (?!--)检查后两个字符不是--,换句话说,[^;]匹配的字符不能第一个-系列为两个--
  • [^;](?<!--)检查匹配[^;]正则表达式引擎后是否无法找到--它是否会回溯两个位置,换句话说[^;]无法查找是--
  • 系列中的最后一个字符

答案 1 :(得分:0)

你需要一个消极的向前看!

此正则表达式将匹配任何不包含原始匹配模式的字符串:

(?!-{2,}.*?;.*).*?;.*

这个正则表达式匹配一个包含分号的字符串,但不是一个在2个或更多个破折号后出现的字符串。

示例:Regex Working

答案 2 :(得分:0)

如何在Java中使用这个正则表达式:

[^;]*;(?<!--[^;]{0,999};).*

唯一需要注意的是,999--之间的字符长度最长为;

Java Regex Demo

答案 3 :(得分:0)

如何只是沿--分割字符串,如果有两个或更多子字符串,检查最后一个字符串是否包含分号?

答案 4 :(得分:0)

我认为这是你正在寻找的东西:

^(?:(?!--).)*;.*$

换句话说,从字符串的开头(^)开始匹配,零个或多个字符(.*)后面跟一个分号。但是用(?:(?!--).)替换点会使其匹配任何字符,除非它是双连字符序列的开头(--

如果性能问题,你也可以排除分号,所以它永远不必回溯:

^(?:(?!--|;).)*;.*$

编辑:我刚刚注意到您的评论,正则表达式应该与matches()方法一起使用,所以我用.*填充了它。锚点并不是必需的,但它们没有任何伤害。