Regexp:排除一个单词,但包含非标准标点符号
Regexp: excluding a word but including non-standard punctuation
我想查找包含按特定顺序排列的单词的字符串,允许在单词之间使用非标准字符,但不包括特定的单词或符号。
我正在使用javascript的replace函数来查找所有实例并放入数组。
所以,我想要select...from
,在单词之间除了'from'以外的任何东西。或者我可以把select...from
和select...from (
分开,只要我排除嵌套。我认为答案是相同的,即我如何写:找到x而不是y在相同的正则表达式?
从互联网上,我觉得这应该工作:/'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
谁能告诉我如何排除这个正则表达式中的单词和符号?
多谢艾玛
编辑:部分字符串输入:
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
Javascript: 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);
Console.log(select)应该打印一个数字数组,其中每个数字都是select...from
的起始字符。这适用于我在info中给出的第二个regexp,打印:[95,251]。你的's' s变体也一样,@stribizhev。
第一个示例^(?!from).*
应该做同样的事情,但返回[]。
第三个示例's*^'(
应该只返回251,但返回[]。然而,我刚刚注意到,积极的表达's*'(
确实给95,所以一些进展!
您的'bselect'b^(?!from).*'bfrom'b
正则表达式不像预期的那样工作,因为:
-
^
这里表示一行的开始,而不是下一部分的否定,所以'bselect'b^
表示,select
字后跟a的开头线。移除^
后,regex开始匹配某些东西(DEMO)但仍然无效。 - 在多行文本
.*
中未经修改将不匹配新行,所以regex将只匹配select...from
单行,但是如果你将其更改为(.|'n)*
(作为一个简单的示例),它将匹配多行,但仍然无效 -
*
是贪婪的量化,所以它会尽可能地匹配,但如果您使用不情愿的量化*?
, regex将首先匹配当from
字出现时,int将开始相对返回正确结果。 -
'bselect'b(?!from)
表示不匹配单独的select
字直接跟在单独的from
单词后面,所以应该是selectfrom
不知何故由单独的单词组成(因为select'bfrom
)所以(?!from)
不工作,它是多余的
实际上你将得到与Stribizhev给你的非常相似的正则表达式:'bselect'b(.|'n)*?'bfrom'b
在第三个表达式中,您犯了同样的错误:'bselect'b[0-9a-zA-Z@'(')'[']'s'.'*,%_+-]*?'bfrom'b's*^'(
使用^
作为(我假设)否定,而不是行开头。删除^
,您将再次获得相对有效的结果(从select
到from
匹配到关闭旁括号)
)。
第二个正则表达式的工作原理类似于'bselect'b(.|'n)*?'bfrom'b
或'bselect'b['s'S]*?'bfrom'b
。
我写了"相对有效的结果",因为我也认为,用正则表达式解析SQL可能非常复杂,所以我不确定它是否会在每种情况下工作。
您也可以尝试使用正向前看来匹配文本中的位置,例如:
(?='bselect'b(?:.|'n)*?'bfrom'b)
DEMO - ()
被添加到regex只是为了返回匹配组的开始索引,所以它会更容易检查它的有效性
正则表达式
我们在字符类中使用^
作为否定,例如[^a-z]
表示匹配除字母以外的任何内容,因此它将匹配数字,符号,空格等,但不匹配a
到z
范围内的字母(看这里)。但这种否定是在单个角色的层面上。如果您使用[^from]
,它将阻止regex匹配字符f
, r
, o
和m
(演示)。此外,[^from]{4}
将避免匹配from
,但也会匹配form
, morf
等。
要通过regex排除整个单词的匹配,您需要使用负查找,如(?!from)
,如果在给定位置后面有被选中的单词from
,则将无法匹配。为了避免匹配包含from
的整行,您可以使用^(?!.*from.*).+$
(demo)。
然而,在你的情况下,你不需要使用这种结构,因为如果你用.*?'bfrom
替换贪婪量化.*'bfrom
,它将匹配这个词的第一次出现。更重要的是,它会带来问题。看看这个正则表达式,它不会匹配任何东西,因为(?!['s'S]*from['s'S]*)
不受任何限制,所以只有在select
之后没有from
时才会匹配,但我们也想匹配from
!实际上,这个正则表达式试图匹配并排除from
,并且失败。因此,(?!.*word.*)
结构可以更好地排除与给定单词匹配的行。
那么,如果我们不匹配匹配片段中的单词该怎么办呢?我认为select'b([^f]|f(?!rom))*?'bfrom'b
是一个很好的解决方案。对于([^f]|f(?!rom))*?
,它将匹配select
和from
之间的所有内容,但不会排除from
。
但是如果你想只匹配select...from
而不匹配(
,那么使用(?!'()
是一个好主意。但是在您的regex(多行)中,使用(.|'n)*?
或['s'S]*?
将导致匹配到下一个select...from
部分,因为不情愿的量化将改变需要匹配的地方以使整个regex。在我看来,好的解决方案是再次使用:
select'b([^f]|f(?!rom))*?'bfrom'b(?!'s*?'()
不会重叠额外的select..from
,如果select...from
后面有'(
,则不会匹配-在这里检查
- 隐藏/显示包含单词的ul li项目.但只能入住李的子女
- 删除javascript中包含特定单词的行
- AJAX数据包含一个或多个单词.
- 输出包含3个单词的字符串中的前2个单词
- 如何使用d3.layout.cloud.js创建一个包含单词及其权重的csv的单词云
- Javascript(如果var包含一个单词,则仅更改该单词的颜色)
- 如果输入包含数组中的任何单词
- 使用 JavaScript split 来包含单词,标点符号与 span 但忽略 HTML
- 要求文本字段包含特定的单词,使用jquery
- 忽略包含特定单词的模式
- 如何根据链接中包含的字母/单词查找并单击链接
- 大写输入字段中包含的每个单词
- 在包含多个单词的表中搜索
- 如何更正包含ä的大写单词öü
- D3.js~如何过滤包含某些值/单词的数据值
- Javascript Regex检查字符串是否包含不属于的单词
- 如何更新单词列表中搜索框中包含用户键入内容的单词/字母数
- 找到包含单词的特定链接并添加到数组中
- 正则表达式以匹配 HTML 范围标记中包含的多个单词
- 如何使用javascript将高亮显示的单词包含在带有一些标签的文本区域中