我正在尝试编写一个可以从mysql字符串中提取字符串值的正则表达式。
也就是说,如果我有以下生成的sql字符串,并且我希望能够提取first_name:
my_string = "SELECT * FROM users WHERE first_name = 'first name value'"
我目前所拥有的功能似乎适用于大多数情况:
result = /first_name = ['"](.*?)['"]/i.match my_string
然而,问题是first_name中有'或',即
result = "SELECT * FROM users WHERE first_name = 'first\"s name value'"
or
result = "SELECT * FROM users WHERE first_name = 'first\\'s name value'"
返回的结果只是转义字符的UP值,因此在这些情况下,返回的组将是“first”。如何修复它以便返回整个first_name值?
答案 0 :(得分:2)
您似乎需要匹配单引号或双引号内的字符串,并且只匹配匹配的引号。
使用Ruby regex功能使用多个具有相同名称的命名组:
/first_name = (?:'(?<val>[^'\\]*(?:\\.[^'\\]*)*)'|"(?<val>[^"\\]*(?:\\.[^"\\]*)*"))/i
请参阅Rubular demo
引号之间的值将在“val”组内。
my_string = "SELECT * FROM users WHERE first_name = 'first name value'"
my_string2 = "SELECT * FROM users WHERE first_name = 'first\"s name value'"
my_string3 = "SELECT * FROM users WHERE first_name = 'first\\'s name value'"
rx = /first_name = (?:'(?<val>[^'\\]*(?:\\.[^'\\]*)*)'|"(?<val>[^"\\]*(?:\\.[^"\\]*)*"))/i
puts rx.match my_string # => first_name = 'first name value'
puts rx.match my_string2 # => first_name = 'first"s name value'
puts rx.match my_string3 # => first_name = 'first\'s name value'
获取“val”(demo):
rx.match(my_string)["val"] # => first name value
由于自Ruby 1.9以来引入了命名组,并且您需要它在Ruby 1.8中工作,因此请使用受前瞻性解决方案限制的字符类。
/first_name = (['"])((?:(?!\1)[^\\])*(?:\\.(?:(?!\1)[^\\])*)*)\1/i
请参阅Rubular demo
(['"])
匹配并捕获到第1组'
或"
。 (?:(?!\1)[^\\])*
匹配除\
以外的0 +字符(由于[^\\]
),而不是"
或'
(由于(?!\1)
) 。 (?:\\.(?:(?!\1)[^\\])*)*)
匹配转义序列的0+序列(请参阅\\.
),其后跟0 {+ 1}},'
或"
以外的0 +字符。 \
反向引用与相应的结束引用匹配。
\1
答案 1 :(得分:0)
答案 2 :(得分:0)
我在Rubular上测试了它,它似乎得到了你正在寻找的价值。唯一的问题是它还可以捕获你可以替换的逃逸字符:
f_name_match = /first_name = \'(.+)\'/i.match(string).replace('\')
答案 3 :(得分:0)