javascript - 正则表达式:排除单词,但包括非标准标点

标签 javascript regex string

我想查找包含按特定顺序排列的单词的字符串,允许在单词之间使用非标准字符,但排除特定的单词或符号。

我正在使用javascript的replace函数来查找所有实例并将其放入数组。

因此,我想要select...from,在单词之间加上“ from”以外的任何内容。或者,只要我不嵌套,就可以将select...fromselect...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(selects)应该打印一个数字数组,其中每个数字都是select...from的起始字符。这适用于我在信息中输入的第二个正则表达式,打印:[95,251]。您的\ s \ S变体也一样,@ stribizhev。

第一个示例^(?!from).*应该也这样做,但返回[]。

第三个示例\s*^\(应该仅返回251,但返回[]。但是我刚刚注意到,正向表达式\s*\(的确给出了95,所以进步了!这是我误会的负面因素。

最佳答案

您的\bselect\b^(?!from).*\bfrom\b正则表达式无法正常运行,因为:


^在这里表示一行的开头,而不是下一部分的否定,所以
\bselect\b^的意思是select单词,后跟一个
线。删除^正则表达式后,开始匹配某些内容
DEMO),但仍然无效。
多行文字.*中未经修改的行将不匹配换行,
因此正则表达式将仅在单行中匹配select...from,但是如果您
将其更改为(.|\n)*(作为简单示例),它将变为match multiline,但仍然无效
*是greetquantfire,因此它将尽可能匹配,
但是,如果您使用勉强的quantifire *?,则正则表达式将与第一个匹配
出现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(从selectfrom匹配到封闭式))。

您的第二个正则表达式的工作方式类似于\bselect\b(.|\n)*?\bfrom\b\bselect\b[\s\S]*?\bfrom\b

正如我也认为的那样,我写了“相对有效的结果”,其中用正则表达式解析SQL可能非常复杂,因此我不确定它是否在每种情况下都可以使用。



您也可以尝试使用正向前瞻来匹配文本中的位置,例如:

(?=\bselect\b(?:.|\n)*?\bfrom\b)


DEMO-将()添加到正则表达式中只是为了返回分组中的匹配开始索引,因此更容易检查其有效性



正则表达式中的否定

我们在字符类中使用^作为否定符,例如[^a-z]表示匹配任何内容,但不匹配字母,因此它将匹配数字,符号,空格等,但不匹配范围az)。但是,这种否定只是在单个字符的层面上。我使用[^from]它将阻止正则表达式匹配字符fromLook here)。同样,[^from]{4}将避免匹配from,但也将避免匹配formmorfdemo

要从正则表达式匹配中排除整个单词,您需要使用负向前看,例如(?!from),如果选择的单词from处于给定位置,则会使用etc。为了避免匹配包含from的整行,可以使用^(?!.*from.*).+$fail to match)。

但是,根据您的情况,您无需使用此构造,因为如果用.*\bfrom替换贪婪的quantifire .*?\bfrom,它将与该词的首次出现相匹配。更何况它会引起问题。看一下demo,它不会匹配任何内容,因为(?![\s\S]*from[\s\S]*)不受任何限制,因此仅当from之后没有select时它才匹配,但我们也想匹配from!实际上,此正则表达式尝试一次匹配并排除from并失败。因此(?!.*word.*)构造可以更好地排除与给定单词匹配的行。

那么,如果我们不匹配匹配片段中的单词,该怎么办?我认为select\b([^f]|f(?!rom))*?\bfrom\bthis regex。对于([^f]|f(?!rom))*?,它将匹配selectfrom之间的所有内容,但不会排除from

但是,如果您只想匹配select...from而不是后跟(,那么最好使用(?!\()这样。但是在您的正则表达式(多行,使用(.|\n)*?[\s\S]*?的情况下,它会导致good solution扩展到下一个select...from部分,因为不情愿的quantfire将在需要匹配以形成整个正则表达式的地方形成一个色带)。意见认为,好的解决方案是再次使用:

select\b([^f]|f(?!rom))*?\bfrom\b(?!\s*?\()


它不会与其他select..from重叠,并且如果\(-match之后有select...from,则不会匹配

关于javascript - 正则表达式:排除单词,但包括非标准标点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32612359/

相关文章:

javascript - 如何在 owlCarousel slider 内容上添加动画

javascript - angularjs .service 无法在 Controller 之间传递变量

javascript - 在下拉过渡中包含 CSS 三 Angular 形

c++ - 如何在忽略特定字符的情况下将单词读入字符串

c - 删除字符串中的一个字符?

javascript - 如何在工厂服务中定义的ng-click中调用函数

java - 模式匹配时如何忽略嵌套括号?

c++ - 使用命名捕获找出给定正则表达式中命名组的所有名称

regex - 拆分一个逗号分隔的列表,其中文本中的逗号不会被转义

c - 在二维数组中打印字符串的各种构象