我在严格的Java环境中。
所以这个问题并不像在Tite中那么简单,我不是在试图解决我遇到的问题,而是为更好的知识提供更多的理论。
我感兴趣的是使用双引号或简单引号匹配src,但如果是双引号,则必须使用双引号关闭,同样适用于简单引用。
我知道我可以重复正则表达式,即:
String str = "src=\"hello/\" ... src='hello/' ..."
println str.replaceAll ("src=((\"[^\"]+\")|('[^']+'))", "src=$1")
我想做的是:
println s.replaceAll ("src=([\"'][^\"']+[\"'])", "src=$1")
但是,如果以双引号开头,则应在内容中允许使用简单引号,并且必须以双引号结束,而不是简单引用。
问题2:
是否可以使用相同类型的引用将其替换为所有? 是否可以说,对于这个匹配,替换为this2,为此,替换为that2。 如何在不每次生成新字符串的情况下实现此目的?
编辑Alan More,问题二的例子:
println "one ... two".replaceAll( "(one)", "1" ).replaceAll("(two)", "2");
更多沿着这些方面(不对)
println "one ... two".replaceMyMatches( "(one)[^\\w]+(two)", "\$1{1}, \$2{2}" ) // prints string : one{1}, two{2}
我想要的是字符串:1,2
回答第一个问题从黑熊猫和杰夫沃克获得并改变了一点:
String str = "src=\"1.png\" ... src='2.jpeg' ... src=\"3.p'ng\" ... src='4.jpe\"g' ... src='' ... src=\"\" ..." ;
String regex = "src=(['\"])(.+?)\\1"; // closes with the quote that is in group 1
println str.replaceAll( regex, '''src=$1../new_path/$2$1''')
吐出:
src="../new_path/1.png" ... src='../new_path/2.jpeg' ... src="../new_path/3.p'ng" ... src='../new_path/4.jpe"g' ... src='' ... src="" ...
如果有人想要替换空的那些,只需将正则表达式中的+与星号切换(我不希望这样)
请注意原始引号也在。
回答问题二看黑熊猫
答案 0 :(得分:2)
问题1的正则表达式是:
src=(['"])hello\1
(Java字符串的双反斜杠)
它使用反向引用匹配第一个引号或双引号,然后匹配与第一个引号相同的字符。
因此,对于更一般的情况,我喜欢:
^src=(['"])(.*?)\1$
然后替换可能是这样的:
String regex = "^src=(['\"])(.*?)\\1$";
String newthing = "src=$2";
这是你想要的吗?基本上剥离引号,同时强制它们匹配?
由于精明的评论,我现在明白你希望引号互相逃避。像Perl这样的语言可以做到这一点,但它们不是通过正则表达式解析的。这种类型的东西属于一类需要实际解析的问题。 (不记得实际的术语)
您必须检查第2组并“断言”第1组不存在,而不是替换。注意到我在正则表达式中添加了开始和结束锚点。
类似于:
Pattern p = Pattern.compile("^src=(['\"])(.*?)\\1$");
Matcher m = p.matcher("src=\"what's up?\"");
if ( m.matches() ) {
if ( m.group(2).contains(m.group(1)) ) {
// fail, doesn't match
}
}
// success, follows all of the rules
即使有更新,我也无法理解你在第二个问题中寻找的内容。如果我得到它,我会编辑这个答案。
答案 1 :(得分:2)
我对问题1的回答最初是不正确的。这是一个更新版本。
回答问题1.如果这个正则表达式可以帮助你: 模式是:
src=(['"])(.*?)\1
下面的代码解释了每一件。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regex {
public static void main(String[] args)
{
final String regex = "src=(['\"])" // the ' or the " is in group 1
+ "(.*?)" // match any character in a non-greedy fashion
+ "\\1"; // closes with the quote that is in group 1
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("src=\"hello/\" ... src='goodbye/' ... "
+ "src='this has a \" in it'");
while (m.find())
{
System.out.println("\nfound!");
System.out.println("The quote was a " + m.group(1));
System.out.println("the text was = " + m.group(2));
}
}
}
这给出了输出:
found!
The quote was a "
the text was = hello/
found!
The quote was a '
the text was = goodbye/
found!
The quote was a '
the text was = this has a " in it
至于第二个问题,你将不得不使用更多的代码。您可以创建自己的StringBuffer并随附。我使用地图来保存替换:
public static void question2()
{
Pattern p = Pattern.compile("one|two");
Map<String, String> replacements = new HashMap<String, String>();
replacements.put("one", "1");
replacements.put("two", "2");
StringBuffer result = new StringBuffer();
String text = "one ... two";
Matcher m = p.matcher(text);
while (m.find())
{
m.appendReplacement(result, replacements.get(m.group()));
}
m.appendTail(result);
System.out.println(result.toString());
}
输出:
1 ... 2
答案 2 :(得分:1)
你可以试试这样的事情
String str = "src=\"hello/\" ... src='hello/' ...";
System.out.println(str.replaceAll("src=([\"'])(.*?)\\1", "src='$2'"));
诀窍是在同一个正则表达式中使用\ 1重用第一个匹配的模式
答案 3 :(得分:0)
对于第一个问题,您可以使用此正则表达式:
"([\"'])(?:(?!\\1).)*\\1"
第二部分没有纯正则表达式解决方案 - 至少不是Java。有关Java方式,请参阅this answer。所以,例如,如果你有一个这样的表:
{ "one" => "1", "two" => "2" }
...您的replacement()
方法会通过在表中查找替换字符串的动态部分,使用捕获组的内容作为键。