无法使用regexp

时间:2018-05-26 09:01:54

标签: ruby regex string

我在这里发表的第一篇文章"显然"必须是关于regexp(所有初学者开发者的噩梦)

我有一个字符串:s = "Shadowborn Apostle \r\nCreature — Human Cleric \r\nA deck can have any number Of \r\ncards named Shadowborn Apostle. \r\ne, Sacrifice six creatures named \r\nShadowborn Apostle: Search your \r\nlibrary for a Demon creature card \r\nand put it onto the battlefield. Then \r\nshuffle your library. \r\n"

我想只提取这部分Shadowborn Apostle(space)

我使用.match来获取我想要的子字符串:s.match(/^[^\\]+/)

不幸的是,MatchData =整个字符串。而且我不确定为什么。任何帮助将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:0)

你的正则表达式^[^\\]+从字符串的开头匹配,直到遇到第一个反斜杠,包括空格,因为否定的character class不匹配反斜杠一次或多次。

也许您可以匹配任何字符一次或多次非贪婪.+?并使用正面lookahead ^.+?(?= \\r)

Demo

如果您想匹配Shadowborn Apostle后跟文本中的空格,您还可以在开头使用单词边界\b,以确保它不是较长匹配的一部分并使用正数在结尾(?= )前瞻以断言后面是一个空格。

\bShadowborn Apostle(?= )

Demo

答案 1 :(得分:0)

您的正则表达式/^[^\\]+/会尝试匹配不是反斜杠的行开头的一个或多个字符。反斜杠字符(ASCII 92)写为92.chr #=> "\\",而换行符(ASCII 13)写为13.chr #=> "\r" 1

因此,您需要/\A[^\r]+/

请注意,我已使用字符串锚点的开头\A,而不是锚的开头,^ 。请考虑以下事项。

"\r\ndog \r".match(/\A[^\r]+/) #=> nil
"\r\ndog \r".match(/^[^\r]+/)  #=> #<MatchData "dog ">

是否使用\A^取决于您希望实现的目标。从此以后我会假设你想要的是\A。 (但是,你应该通过编辑问题来清楚说明。如上所述,所需的子字符串不需要从字符串的开头或一行开始。)

继续,

r = /\A[^\r]+/
m = s.match(r) #=> #<MatchData "Shadowborn Apostle ">
m[0] #=> "Shadowborn Apostle "

或(代替m[0]):

$&   #=> "Shadowborn Apostle "

或简单地说:

s[r] #=> "Shadowborn Apostle "

请参阅MatchData#[]String#[]

如果结束空格是可选的,这很好。但是,如果字符串必须以空格结尾,我们必须对正则表达式稍作调整:

r = /\A[^\r]+ /

最后,这是另一种获取不使用正则表达式的子字符串的方法:

 idx = s.index(" \r")
   #=> 18
 idx.nil? ? nil : s[0, idx+1]
   #=> "Shadowborn Apostle "

 idx = "How now, brown cow".index(" \r")
   #=> nil
 idx.nil? ? nil : s[0,idx+1]
   #=> nil

请参阅String#index

1为什么不能使用单个反斜杠(/^[^\]+/)?因为Ruby会启动字符类("["),所以请阅读&#39;否定&#39; ("^")转义右括号"\]"(解释为字符"]")和"+"。当下一个字符"/"终止正则表达式时,她会断定字符类没有关闭,因此引发异常(SyntaxError)。