正则表达式捕获不需要的字符串

时间:2013-07-05 20:01:27

标签: regex

我创建了以下表达式:( .NET正则表达式引擎)

((-|\+)?\w+(\^\.?\d+)?)

hello , hello^.555,hello^111, -hello,+hello, hello+, hello^.25, hello^-1212121

除了:

以外,效果很好
  • 它捕获术语'hello +'但没有'+':不应该捕获该组
  • 最后一个词'hello ^ -1212121'为2组'hello'和'-1212121'都应该被忽略

要捕获的字符串如下:

  • word之前可以有+或a -
  • 或word可以有^后跟一个正数(不一定是整数)
  • 单词用逗号和任意数量的空格分隔(两者都不是捕获的一部分)

要捕获的有效字符串的几个示例:

  • 你好^ 2
  • 你好^ 0.2
  • +你好
  • 你好
  • 你好

修改

我发现以下表达式有效地捕获了所有这些术语,它并没有真正优化但只是起作用:

([a-zA-Z]+(?= ?,))|((-|\+)[a-zA-Z]+(?=,))|([a-zA-Z]+\^\.?\d+)

2 个答案:

答案 0 :(得分:2)

好的,这里有一些问题需要解决:

((-|+)?\w+(\^.?\d+)?)
    ^        ^

+.应该像这样转义:

((-|\+)?\w+(\^\.?\d+)?)

现在,您还可以获得-1212121。如果您的字符串hello始终是字母,那么您可以将\w更改为[a-zA-Z]

((-|\+)?[a-zA-Z]+(\^\.?\d+)?)

\w包括字母,数字和下划线。因此,您可能希望将其限制为仅限于字母。

最后,考虑到完全不捕获的群体,你必须使用外观。不管怎样我都不知道在不妨碍比赛的情况下到达分隔符:

(?<=^|,)\s*((-|\+)?[a-zA-Z]+(\^\.?\d+)?)\s*(?=,|$)

编辑:如果它不能像-hello^2那样,如果另一个有效字符串是hello^9.8,那么这个字符串会更合适:

(?<=^|,)\s*((?:-|\+)?[a-zA-Z]+|[a-zA-Z]+\^(?:\d+)?\.?\d+)(?=\s*(?:,|$))

最后,如果捕获单词就足够了,我们可以删除外观:

([-+]?[a-zA-Z]+|[a-zA-Z]+\^(?:\d+)?\.?\d+)

答案 1 :(得分:1)

如果您首先陈述您要提取的内容会更好。

您也没有指出您正在使用哪个正则表达式引擎,这很重要,因为它们的功能各不相同,但是......

假设您只想捕获:

  • 具有前导+或 -
  • 的字词
  • 具有尾随^后跟可选句点后跟一个或多个数字
  • 的单词

并且该单词是一个或多个字母的序列

我会用:

([a-zA-Z]+\^\.?\d+|[-+][a-zA-Z]+)

分解为:

(              # start capture group
    [a-zA-Z]+    # one or more letters - note \w matches numbers and underscores
    \^           # literal
    \.?          # optional period
    \d+          # one or more digits
|              # OR
    [+-]?        # optional plus or minus
    [a-zA-Z]+    # one or more letters or underscores
)              # end of capture group

修改

要捕获普通单词(没有前导或尾随字符),您需要稍微重新排列正则表达式。我会用:

([+-][a-zA-Z]+|[a-zA-Z]+\^(?:\.\d+|\d+\.\d+|\d+)|[a-zA-Z]+)

分解为:

(              # start capture group
    [+-]         # literal plus or minus
    [a-zA-Z]+    # one or more letters - note \w matches numbers and underscores
|              # OR
    [a-zA-Z]+    # one or more letters
    \^           # literal
    (?:          # start of non-capturing group
      \.           # literal period
      \d+          # one or more digits
    |            # OR
      \d+          # one or more digits       
      \.           # literal period
      \d+          # one or more digits
    |            # OR
      \d+          # one or more digits 
    )            # end of non-capturing group
|              # OR
    [a-zA-Z]+    # one or more letters
)              # end of capture group

另请注意,根据您更新的要求,此正则表达式捕获真正的非负数(即0,1,1.2,1.23)以及缺少前导数字的那些(即.1,.12)

进一步编辑

此正则表达式仅匹配以逗号分隔的以下模式:

  • 带前导加减号的单词
  • 带有尾随^的单词后跟一个正数的形式\ d +,\ d +。\ d +,或。\ d +

    ([+ - ] [A-ZA-Z] + | [A-ZA-Z] + \ ^(?:??\ d + | \ d +(:\ d +))| [A-ZA -z] +)(=,|?\ S | $)

请注意,有用的匹配将显示在第一个捕获组中,整个匹配。

所以,在Javascript中,你要:

var src="hello ,  hello ,hello,+hello,-hello,hello+,hello-,hello^1,hello^1.0,hello^.1",
    RE=/([+-][A-Za-z]+|[A-Za-z]+\^(?:\.\d+|\d+(?:\.\d+)?)|[A-Za-z]+)(?=,|\s|$)/g;

while(RE.test(src)){
    console.log(RegExp.$1)
}

产生:

hello
hello
hello
+hello
-hello
hello^1
hello^1.0
hello^.1