我想找到包含特定顺序单词的字符串,允许单词之间使用非标准字符,但不包括特定的单词或符号。
我使用javascript的替换函数来查找所有实例并放入数组。
所以,我希望React-Native
,除了'之外的所有内容。在两个词之间。或者我可以将select...from
与select...from
分开,只要我排除嵌套即可。我认为答案对两者都是一样的,即如何写:在同一个正则表达式中找到x而不是y ?
从互联网上,我觉得这应该有效:select...from (
但是没有找到匹配项。
这可以找到所有/\bselect\b^(?!from).*\bfrom\b/gi
:select...from
但修改它以排除括号"("最后会阻止任何匹配:/\bselect\b[0-9a-zA-Z@\(\)\[\]\s\.\*,%_+-]*?\bfrom\b/gi
有人能告诉我如何排除此正则表达式中的单词和符号吗?
非常感谢 艾玛
编辑:部分字符串输入:
/\bselect\b[0-9a-zA-Z@\(\)\[\]\s\.\*,%_+-]*?\bfrom\b\s*^\(/gi
使用Javascript:
left outer join [stage].[db].[table14] o on p.Project_id = o.project_id
left outer join
(
select
different_id
,sum(costs) - ( sum(brushes) + sum(carpets) + sum(fabric) + sum(other) + sum(chairs)+ sum(apples) ) as overallNumber
from
(
select ace from [stage].db.[table18] J
Console.log(选择)应该打印一个数字数组,其中每个数字都是sequel = stringInputAsAbove;
var tst = sequel.replace(/\bselect\b[\s\S]*?\bfrom\b/gi, function(a,b) { console.log('match: '+a); selects.push(b); return a; });
console.log(selects);
的起始字符。这适用于我在我的信息中提供的第二个正则表达式,打印:[95,251]。您的\ s \ S变体也是如此,@ sszizhev。
第一个示例select...from
也应该这样做但返回[]。
第三个示例^(?!from).*
应仅返回251但返回[]。但是我刚刚注意到正面表达式\s*^\(
确实给出了95,所以有些进步!这是我出错的消极因素。
答案 0 :(得分:1)
您的\bselect\b^(?!from).*\bfrom\b
正则表达式无法按预期工作,因为:
^
表示行的开头,而不是对下一部分的否定,所以
\bselect\b^
表示select
字后跟a的开头
线。删除^
正则表达式后开始匹配的东西
(DEMO)但它仍然无效。.*
中没有修改的select...from
,但如果你
更改(.|\n)*
(作为一个简单示例)它将match
multiline,但仍然无效*
是量化的,所以它会尽可能匹配,
但如果你使用不情愿的量词*?
,正则表达式将首先匹配
from
字的出现,而int将开始返回relativly
correct result。\bselect\b(?!from)
表示匹配单独的select
字词
紧接着是单独的from
字,所以它会是
selectfrom
以某种方式由单独的单词组成(因为
select\bfrom
)所以(?!from)
无效,redundant 实际上你会得到正则表达式与Stribizhev给你的非常相似:\bselect\b(.|\n)*?\bfrom\b
在第三个表达式中你犯了同样的错误:\bselect\b[0-9a-zA-Z@\(\)\[\]\s\.\*,%_+-]*?\bfrom\b\s*^\(
使用^
作为(我假设)否定,而不是一行的开头。移除^
,您将再次获得相对有效result(从select
到from
匹配到结束时的)
}。
您的第二个正则表达式与\bselect\b(.|\n)*?\bfrom\b
或\bselect\b[\s\S]*?\bfrom\b
类似。
我写了#34;相对有效的结果",我也认为,用正则表达式解析SQL可能非常复杂,所以我不确定它是否适用于所有情况。
您还可以尝试使用正向前瞻来匹配文本中的位置,例如:
(?=\bselect\b(?:.|\n)*?\bfrom\b)
DEMO - ()
已添加到正则表达式,只是为了返回组中匹配的开始索引,因此检查其有效性会更容易
我们在字符类中使用^
作为否定,例如[^a-z]
表示匹配任何内容但不匹配字母,因此它将匹配数字,符号,空格等,但不匹配范围{{1 } a
(Look here)。但这种否定是单一性的。我使用z
它会阻止正则表达式匹配字符[^from]
,f
,r
和o
(demo)。此外,m
将避免匹配[^from]{4}
,还会from
,form
,etc。
要通过正则表达式来匹配整个单词,您需要使用负面预测,例如morf
,这将fail to match,如果将选择单词(?!from)
,则会放弃给定位置。为避免匹配包含from
的整行,您可以使用from
(demo)。
但是在您的情况下,您不需要使用此构造,因为如果您将贪婪量化^(?!.*from.*).+$
替换为.*\bfrom
,它将与该单词的首次出现相匹配。更重要的是会遇到问题。看看this regex,它不会匹配任何内容,因为.*?\bfrom
不受任何限制,所以只有在(?![\s\S]*from[\s\S]*)
之后没有from
时它才会匹配,但我们想要匹配select
!实际上,这个正则表达式试图立即匹配和排除from
,并失败。所以from
构造更好地排除匹配的行与给定的单词。
那么,如果我们不匹配匹配片段中的单词,该怎么办?我认为(?!.*word.*)
是good solution。使用select\b([^f]|f(?!rom))*?\bfrom\b
,它会匹配([^f]|f(?!rom))*?
和select
之间的所有内容,但不会排除from
。
但是,如果您只想匹配from
而不是select...from
,那么最好使用(
之类的。但是在你的正则表达式(多行,使用(?!\()
或(.|\n)*?
时,它会导致match到下一个[\s\S]*?
部分,因为不情愿的量化将会改变它需要的地方匹配使整个正则表达式。在我看来,好的解决方案是再次使用:
select...from
不会与其他select\b([^f]|f(?!rom))*?\bfrom\b(?!\s*?\()
重叠,如果在select..from
之后\(
- check it here