2

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

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

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

它运作良好,除了:

  • 它捕获了术语 'hello+' 但没有 '+' :根本不应该捕获这个组
  • 最后一个词'hello^-1212121'作为2组'hello'和'-1212121'都应该被忽略

要捕获的字符串如下:

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

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

  • 你好^2
  • 你好^.2
  • +你好
  • -你好
  • 你好

编辑

我发现以下表达式有效地捕捉了所有这些术语,它并没有真正优化,但它确实有效:

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

2 回答 2

2

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

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

+and.应该像这样转义:

((-|\+)?\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+)
于 2013-07-05T20:08:07.543 回答
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)以及缺少前导数字的那些(即 0.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
于 2013-07-05T20:38:38.233 回答