用于查找javascript字符串内外文本的正则表达式?

用于查找javascript字符串内外文本的正则表达式?,javascript,regex,Javascript,Regex,我正在搜索网站资源(html和javascript)中的文本,需要确定3个正则表达式,在某些情况下可以定位此文本: 包含在javascript单引号字符串中的某些文本字符串 包含在javascript双引号字符串中的某些文本字符串 当某个文本字符串不包含在javascript字符串中时 以下是可能发生的一些情况(搜索字符串“somestring”): 这些示例可能都出现在同一个文件中,因此正则表达式不应假定为单一情况 我尝试了以下方法来查找单引号和双引号字符串,但不幸的是,我失败了: 单引号:

我正在搜索网站资源(html和javascript)中的文本,需要确定3个正则表达式,在某些情况下可以定位此文本:

  • 包含在javascript单引号字符串中的某些文本字符串
  • 包含在javascript双引号字符串中的某些文本字符串
  • 当某个文本字符串不包含在javascript字符串中时
  • 以下是可能发生的一些情况(搜索字符串“somestring”):

    这些示例可能都出现在同一个文件中,因此正则表达式不应假定为单一情况

    我尝试了以下方法来查找单引号和双引号字符串,但不幸的是,我失败了:

    单引号:

    ([=|(|\+]\s*?'[^']*?(?:'[^']*?'[^']*?)*?somestring)
    
    ([=|(|\+]\s*?"[^"]*?(?:"[^"]*?"[^"]*?)*?somestring)
    
    双引号:

    ([=|(|\+]\s*?'[^']*?(?:'[^']*?'[^']*?)*?somestring)
    
    ([=|(|\+]\s*?"[^"]*?(?:"[^"]*?"[^"]*?)*?somestring)
    
    在假设正确的条件下,这些都可以工作,但我尝试过的许多现实场景(读取真实的javascript文件)都失败了。非常感谢您的帮助


    编辑:为了澄清,我正在为上面列出的每个条件寻找3个正则表达式,而不是一个涵盖所有情况的正则表达式。

    考虑一个初始“解析”(我松散地使用该术语),它生成三个不同的结果流——每个搜索域一个

    在这个阶段中,只需在标记
    /
    '
    上增加文件停止的步骤,因为这些标记更改了“上下文”(可能的注释、正则表达式或字符串)。然后确定(对于
    /
    情况)并使用上下文内容,并将其放入相应的结果流中。(在像
    “foo\”bar\\“
    这样的情况下,查找结尾仍然有点棘手,但比正则表达式在搜索中尝试匹配上下文要简单得多。)

    当这个阶段完成时——除了可验证之外——每个单独的流都可以很容易地独立搜索


    愉快的编码。

    三个正则表达式无法在所有情况下正确处理此问题,因为JavaScript没有规则的词汇语法:不可能总是确定引号是否开始字符串

    即使假设您可以正确识别并忽略注释中的引号,正则表达式中的引号也会使您感到沮丧

    比如说,

    x++/y - "42" /i
    
    vs

    在第一种情况下,引号是字符串的一部分

    ((x++) / (y - 42)) / i
    
    x = ++(new RegExp('y - "42"', 'i'))
    
    但是在第二种情况下,引号不是字符串的一部分

    ((x++) / (y - 42)) / i
    
    x = ++(new RegExp('y - "42"', 'i'))
    
    这是一个语法上有效但毫无意义的JavaScript语句

    如果您愿意忽略像这样的注释和奇怪的构造,那么您可以使用

    /"(?:[^"\\]|\\(?:[^\r]|\r\n?))*"/
    

    这将使EcmaScript 5样式的字符串与行连续体匹配。

    请小心您的要求! 使用正则表达式可以很好地实现三个目标中的前两个,但它不是微不足道的,也不是100%可靠的(请参见下面的注意事项)

    从JavaScript中提取字符串 首先,让我们看看如何从纯Javascript代码(非HTML)的较长字符串中选择单引号和双引号子字符串。请注意,要正确执行此操作,正则表达式不仅必须匹配两种类型的引号字符串,还必须匹配单行和多行注释。这是因为引号可能出现在注释中(例如,
    /*我不能接受!*/
    ),必须忽略这些引号。此外,注释分隔符可能会出现在带引号的字符串中(例如,
    var str=“This:/*也可能导致问题!”;
    ),因此所有四个构造都必须在一个过程中解析出来。下面是一个正则表达式,它匹配两种类型的注释和两种类型的带引号的字符串。它以带注释的详细模式显示(使用PHP单引号语法):

    $re='%#解析javascript代码中的注释和引用字符串。
    /\*[^*]*\*+(?:[^*/][^*]*\*+)*/#多行注释,或
    |(\'[^\'\\\]*(?:\\\\[\S\S][^\'\\\]*)*\$1:单引号字符串,或
    |(“[^”\\\]*(?:\\\\[\S\S][^”\\\]*)*”)\$2:双引号字符串,或
    |//.#一行注释。
    %x′;
    
    此正则表达式将单引号字符串捕获到组
    $1
    中,并将双引号字符串捕获到组
    $2
    (任何一种类型的字符串都可能包含转义字符,例如
    “太酷了!”
    )。当捕获组
    $1
    $2
    都不匹配时,这两种类型的注释都会被整体匹配捕获。此外,请注意,此正则表达式实现了Jeffrey Friedl的“展开循环”效率技巧(请参见:),因此速度相当快

    process_js()

    以下Javascript函数:
    process_js()
    ,实现上述正则表达式(使用非详细的本机Javascript正则表达式文字语法)使用独立处理单引号和双引号字符串并保留所有注释的匿名函数替换。另外两个函数:
    process\u sq()
    process\u dq()
    分别对匹配的单引号和双引号字符串执行处理:

    函数进程_js(text){
    //处理注释外的单引号和双引号字符串。
    变量re=/\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\/\*('[^'\]*(?:\\[\S\S][^'\]*)*)。(“[^”\]*(?:\\[\S\S][^'\]*)*”)。\/\/*/g;
    返回文本。替换(重新,
    功能(m0、m1、m2){
    if(m1)返回过程_sq(m1);/“单引号”。
    if(m2)返回过程_dq(m2);/“双引号”。
    返回m0;//保留注释。
    });
    }
    功能过程(文本){
    返回文本。替换(/\bsomestring\b/g,'SOMESTRING_SQ');
    }
    函数过程_dq(文本){
    返回文本。替换(/\bsomestring\b/g,'SOMESTRING_DQ');
    }
    
    请注意,两个带引号的字符串处理函数仅替换