Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这个正则表达式没有给出预期的输出?_Java_Regex_String_String Matching - Fatal编程技术网

Java 为什么这个正则表达式没有给出预期的输出?

Java 为什么这个正则表达式没有给出预期的输出?,java,regex,string,string-matching,Java,Regex,String,String Matching,我有一个字符串,其中包含一些值,如下所示。我想用一些新文本替换包含特定customerId的html img标记。我尝试了一个小的java程序,它没有给我预期的输出 我的输入字符串是 String inputText = "Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123/></p>" + "<p>someText</

我有一个字符串,其中包含一些值,如下所示。我想用一些新文本替换包含特定customerId的html img标记。我尝试了一个小的java程序,它没有给我预期的输出

我的输入字符串是

 String inputText = "Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123/></p>"
    + "<p>someText</p><img src=\"getCustomers.do?custCode=2&customerId=3340&param2=456/> ..Ending here";
输出为

  String outputText = inputText.replaceAll(regex, newText);
 Starting here.. Replacing Text ..Ending here
但我的预期产出是

 Starting here.. Replacing Text ..Ending here
从这里开始

someText

替换文本..到此结束
请注意,在我的预期输出中,只有包含customerId=3340的img标记被替换为替换文本。我不明白为什么在输出中我得到了两个img标记都得到了回复?

您有“通配符”/“任意”模式(
*
),它将匹配扩展到可能的最长匹配字符串,模式中的最后一个固定文本是一个
字符,因此,它匹配输入文本中的最后一个
字符,即最后一个

您应该能够通过将
*
部分更改为类似
[^>]+
的内容来解决此问题,以便匹配不会跨越第一个
字符

用正则表达式解析HTML肯定会带来麻烦。

其中有“通配符”/“任意”模式(
*
),它将匹配扩展到可能最长的匹配字符串,模式中的最后一个固定文本是一个
字符,因此与输入文本中的最后一个
字符匹配,就是最后一个

您应该能够通过将
*
部分更改为类似
[^>]+
的内容来解决此问题,以便匹配不会跨越第一个
字符


用正则表达式解析HTML肯定会带来痛苦。

正如其他人在评论中告诉你的那样,HTML不是一种正则语言,因此使用正则表达式来处理它通常是痛苦的。最好的选择是使用HTML解析器。我以前没有使用过Jsoup,但在谷歌上搜索一下,似乎您需要一些类似的东西:

 Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123/></p><p>someText</p>Replacing Text ..Ending here
然后在列表上循环并用一些文本替换这些节点

更新

如果您不想用文本替换整个
img
节点,而是需要为其
src
属性指定一个新值,则可以用以下内容替换
for
循环的块:

Elements myImgs = doc.select("img[src*=customerId=3340");
或者,如果您只想更改
src
值的一部分,则可以执行以下操作:

element.attr("src", "my new value"));

这与我发布的内容非常相似。

正如其他人在评论中告诉你的,HTML不是一种常规语言,因此使用正则表达式来处理它通常是痛苦的。最好的选择是使用HTML解析器。我以前没有使用过Jsoup,但在谷歌上搜索一下,似乎您需要一些类似的东西:

 Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123/></p><p>someText</p>Replacing Text ..Ending here
然后在列表上循环并用一些文本替换这些节点

更新

如果您不想用文本替换整个
img
节点,而是需要为其
src
属性指定一个新值,则可以用以下内容替换
for
循环的块:

Elements myImgs = doc.select("img[src*=customerId=3340");
或者,如果您只想更改
src
值的一部分,则可以执行以下操作:

element.attr("src", "my new value"));

这与我发布的内容非常相似。

发生的情况是,您的正则表达式开始匹配第一个img标记,然后消耗所有内容(无论是否贪婪),直到找到customerId=3340,然后继续消耗所有内容,直到找到>

如果您想让它只使用customerId=3340的img,那么请考虑是什么使该标记与它可能匹配的其他标记不同

在这种特殊情况下,一种可能的解决方案是使用look-behind操作符(不使用匹配项)查看img标记后面的内容。此正则表达式将在以下情况下工作:

String srcValue = element.attr("src");
element.attr("src", srcValue.replace("getCustomers.do", "getCustonerNew.do"));

String regex=“(?发生的情况是,您的regex开始匹配第一个img标记,然后消耗所有内容(不管是否贪婪),直到找到customerId=3340,然后继续消耗所有内容,直到找到>

如果您想让它只使用customerId=3340的img,那么请考虑是什么使该标记与它可能匹配的其他标记不同

在这种特殊情况下,一种可能的解决方案是使用look-behind操作符(不使用匹配项)查看img标记后面的内容。此正则表达式将工作:

String srcValue = element.attr("src");
element.attr("src", srcValue.replace("getCustomers.do", "getCustonerNew.do"));

String regex=“(?您正在使用regex解析html,这永远不会完全起作用(这是对regex的限制,而不是您的regexing技能)你使用了一个错误的工具..使用html解析器@Some1.Kill.The.DJ你能帮助我如何使用jsoup这样的html解析器获得预期结果吗?M Sach你可以看到我的答案,了解jsoup工作的完整示例。你使用的正则表达式解析html永远不会完全工作(这是对正则表达式的限制,而不是你的正则表达式技能)你使用了一个错误的工具。.使用html解析器@Some1.Kill.The.DJ你能帮助我如何使用jsoup这样的html解析器获得预期的结果吗?M Sach你可以看到我的答案,了解jsoup工作的完整示例。@Greg我可以使用jsoup库获得预期的输出吗?
*?
实际上与
*
没有任何不同。零个或更多匹配项零个或多个字符是零个或多个字符,包括任意数量的
字符。对不起,我不使用Java,我刚刚发现了一个典型的重新设计错误。你是说这样的“(?s)\\\]+?customerId=3340[^>]+?>”?它似乎在工作,但不确定您是否试图传达相同的正则表达式?@GregA.Woods
*?
(*)不同?
。如果在重复量词之后有一个
,则将其取消冻结。这确实会有所不同。@Greg我可以使用jsoup库获得预期的输出吗?
*?
实际上与
*
没有任何区别。零个或多个字符的零个或多个匹配就是零个或多个字符,包括任何数量的ode>
字符。对不起,我不懂Java,我只会识别