我正在尝试匹配JS代码块并使用Java提取包含给定关键字的字符串文字。
在尝试使用我自己的正则表达式执行此操作后,我最终修改了这个通用的字符串 - 文字匹配regexp(在Java中构建模式时使用的Pattern.COMMENTS):
(["']) (?:\\?+.)*? \1
以下
(["']) (?:\\?+.)*? keyword (?:\\?+.)*? \1
测试用例:
var v1 = "test";
var v2 = "testkeyword";
var v3 = "test"; var v4 = "testkeyword";
正则表达式与第1行正确匹配,并且与第2行正确匹配。
但是,在第3行中,它不是仅匹配“testkeyword”,而是匹配块
"test"; var v4 = "testkeyword"
这是错误的 - 正则表达式匹配第一个双引号并且没有在第二个双引号处终止,一直持续到行尾。
有没有人对如何解决这个问题有任何想法?
PS:请记住,Regexp必须正确处理字符串文字中的转义单引号和双引号字符(广义匹配器已经这样做了)。
答案 0 :(得分:3)
这次修改怎么样:
(?:
"
(?:\\"|[^"\r\n])*
keyword
(?:\\"|[^"\r\n])*
"
|
'
(?:\\'|[^'\r\n])*
keyword
(?:\\'|[^'\r\n])*
'
)
答案 1 :(得分:1)
经过多次修改(参见编辑历史,主页观众:),我相信这是我的最终答案:
(?:
"
(?:\\?+"|[^"])*
keyword
(?:\\?+"|[^"])*
"
|
'
(?:\\?+'|[^'])*
keyword
(?:\\?+'|[^'])*
'
)
答案 2 :(得分:0)
你需要为单引号或双引号字符串编写两种模式,因为没有办法让正则表达式记住打开字符串。然后你可以和他们一起|。
答案 3 :(得分:0)
考虑使用Rhino中的代码 - Java中的JS - 来获得真正的字符串文字。
或者,如果你想使用正则表达式,考虑一个查找整个文字,然后一个嵌套测试,如果文字包含'关键字'。
我认为Tim的建设有效,但我不会在所有情况下都打赌它,如果必须处理那些不想被发现的文字,那么正则表达式就必须变得非常笨拙(好像试图偷偷摸摸你的测试)。例如:
var v5 = "test\x6b\u0065yword"
与任何解决方案分开,我交互式制作正则表达式的秘密武器是我创建的一个名为Regex Powertoy的工具,与许多此类实用程序不同,它可以在任何支持Java applet的浏览器中运行。
答案 4 :(得分:0)
构造字符串文字的语法大致如下:
string-literal ::= quote text quote text ::= character text | character character ::= non-quote | backslash quote
非引号,反斜杠和引用为终端。
如果语法是无上下文的(即所有规则的左侧始终是单个非终端),并且所有规则的右侧始终为空,终端或终端,则语法是常规的一个非终端。
您可能会注意到上面给出的第一条规则有一个终端,后跟一个非终结符,后跟一个终端。因此,这不是常规语法。
正则表达式是一种可以解析常规语言的表达式(可以通过常规语法构造的语言)。使用正则表达式解析非常规语言是不可能的。
您在寻找合适的正则表达式时遇到的困难源于不存在合适的正则表达式的事实。你永远不会以这种方式得到明显正确的代码。
按照上述规则编写简单的解析器要容易得多。由于您的字符串文字包含的 文本是常规的,因此您可以使用简单的正则表达式查找提取后的关键字--- 来自周围的文字。