正则表达式将匹配不以“ km”结尾的字母和数字的组合

时间:2018-11-20 02:05:08

标签: ruby regex

我是新来的,所以我会努力的。

我一行包含不同的汽车信息。

  

65101公里,轿车,手动,18131A,前轮驱动,二手,5.5升/ 100公里,丰田,凯美瑞,SE,{AC,加热座椅,加热后视镜,无钥匙进入},2010

我正在尝试编写一个正则表达式,以匹配该行中不以“ km”结尾的字母和数字的组合。 每个汽车制造商之间的序列号可能会有所不同。 例如:

  

18FO724A,18131A,19BF723A

这些是来自不同车型的序列号。

我尝试过:

/((?:[a-zA-Z]+[0-9]+[^km]$|[0-9]+[a-zA-Z])[a-zA-Z0-9])/

但是它继续返回公里数

  

65101公里

我需要的答案是

  

18131A

任何帮助都可以。 谢谢

3 个答案:

答案 0 :(得分:1)

从您提供的示例中,您的序列号似乎总是以数字开头,以字母结尾-如果不正确,请参考my comment,然后仔细阅读将如何为您提供更好的帮助。

此模式应该有效:

/(\d+[a-z0-9]+[a-z](?<!km\b))(?:,|$)/i

这需要满足以下条件:

  • \d+至少以一个或多个+\d开头
  • [a-z0-9]+后跟任意字母数字字符[a-z0-9],一次或多次+
  • (?<!km\b))(?:,|$)表示字符串的否定超前行以逗号,或字符串$结束,但不是在字母km (?<!km\b)之后li>

这使用单个捕获组(...),因此您不包括整个匹配项随附的逗号,

regex101上查看

答案 1 :(得分:0)

我的理解是,给定一个字符串,您希望附加具有以下属性的所有子字符串:

  • 子字符串以逗号开头或以逗号开头,后跟逗号或以字符串结尾;
  • 子字符串仅包含字母数字字符(数字和字母);
  • 子字符串包含至少一位数字;
  • 子字符串至少包含一个字母;和
  • 子字符串不能以字符串"km"结尾。

测试字符串如下。

str = "65101km,Sedan,Manual,18131A,FWD,Used,5.5L/100km,Toyota,camry,SE," +
      "{AC, Heated Seats, Heated Mirrors, Keyless Entry},2010,208A1,28km1"

请注意,我已经在问题中使用",208A1,28km1"附加了字符串。

您可以使用带有以下正则表达式的方法String#scan提取所需的子字符串。

r = /
    (?<=\A|,)      # match the beginning of the string or a comma in a positive lookbehind
    (?:            # begin a non-capture group
      \p{Digit}+   # match one or more digits
      \p{Alpha}+   # match one or more letters
      |            # or
      \p{Alpha}+   # match one or more letters
      \p{Digit}+   # match one or more digits
    )              # end non-capture group
   \p{Alnum}*      # match zero or more letter or digits
   (?<!km)         # do not match 'km' (negative lookbehing)
   (?=,|\z)        # match a comma or the end of the string in a positive lookahead
   /x              # free-spacing regex definition mode

str.scan(r)
   #=> ["18131A", "208A1"]

或者,您可以通过四个简单的步骤来做到这一点。

str.split(',').select do |s| s.match?(/\A\p{Alnum}+\z/) &&
                             s.match?(/\p{Alpha}/) &&
                             s.match?(/\p{Digit}/) &&
                             !s.end_with?("km")
                      end
  #=> ["18131A", "208A1"]

\p{} 构造的文档可以通过在Regexp中进行搜索来找到。它们类似于 POSIX括号类,它们记录在同一文件中。

答案 2 :(得分:0)

我将首先用逗号将这一行拆分为多个项目,然后将正则表达式应用于每个项目:

input = "65101km,Sedan,Manual,18131A,FWD,Used,5.5L/100km,Toyota," \
        "camry,SE,{AC, Heated Seats, Heated Mirrors, Keyless Entry},2010"
input.split(',').grep(/^(?!.*km)\d+\p{l}+$/)
#⇒ ["18131A"]

上面的代码返回一个数组,因此您可能希望以某种方式处理它(例如,使用first。)

正则表达式本身匹配所有项目,遵循与\d+\p{l}+(开头negative lookahead不匹配)km的模式。