我正在尝试从给定的字符串中提取值,该值可能包含许多带有该模式的标记,例如
<element1>content1</element1><element2>content2</element2><element3>content3</element3>... and so on.
当前这是我正在使用的带有正则表达式的代码。
String tempString = "<element1>content1</element1><element2>content2</element2>";
String[] tempArray = tempString.split("(<\\w+>)|(</\\w+>)");
for (String item : tempArray) {
System.out.println("Item: " + item);
}
我期望的结果是:
Item: content1
Item: content2
etc...
相反,我收到:
Item:
Item: content1
Item:
Item: content2
我只想使用一种划线-一种魔术正则表达式来消除这些空元素。我的意思是-在给定的字符串上,我将该表达式作为一行应用,并且神奇地我在数组中收到了期望的值-无需进一步处理或分组。 甚至有可能实现吗?
答案 0 :(得分:3)
您可以利用捕获组的反向引用和惰性量词来动态获取所有内容:
<(element\d+)>(.*?)<\/\1>
<(element\d+)>
-找到一个名为“ element”的标签,后跟至少一个数字,并将其放入$1
(例如element1
)(.*?)
-懒惰地将所有内容捕获到$2
中,直到下一条正则表达式指令成功<\/\1>
-使用\1
引用我们在$1
中捕获的内容,并将其作为结束标记进行匹配和$2
将包含:
content1
content2
content3
https://regex101.com/r/NAImHv/1/
您可以使用Java - Extract strings with Regex使我的正则表达式适合Java代码。
免责声明:正则表达式绝对是错误的工具,您绝对应该研究XPath,但这是一个快速解决问题的方法,如果您可以避免遇到极端情况的话。 >
答案 1 :(得分:0)
使用现有的代码片段,您可以使用一些正则表达式应用以下代码来实现它。 看看下面的代码
导入正则表达式实用程序
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String pattern = "\\w+";
Pattern r = Pattern.compile(pattern);
String tempString =
"<element1>content1</element1><element2>content2</element2>";
String[] tempArray = tempString.split ("(<\\w+>)|(</\\w+>)");
for (String item:tempArray)
{
Matcher matcher = r.matcher(item);
//check if the pattern matches
if(matcher.matches()){
System.out.println ("Item: " + item);
}
}
希望这会有所帮助
谢谢
答案 2 :(得分:0)
如果可以使用流,则可以使用正则表达式,然后过滤掉空的正则表达式:
String tempString = "<element1>content1</element1><element2>content2</element2>";
String[] tempArray = Pattern.compile("(<\\w+>)|(</\\w+>)").splitAsStream(tempString)
.filter(s -> !s.isEmpty()).toArray(String[]::new);
System.out.println(Arrays.toString(tempArray));
答案 3 :(得分:0)
另一种解决方案是使用Xpath:
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Extract {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
// Q 57876359
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
String xml = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<elements>\r\n" +
" <element1>content1</element1>\r\n" +
" <element2>content2</element2>\r\n" +
" <element3>content3</element3>\r\n" +
"</elements>");
InputSource is = new InputSource(new StringReader(xml));
Document doc = builder.parse(is);
XPathFactory xpathfactory = XPathFactory.newInstance();
XPath xpath = xpathfactory.newXPath();
int nodes = doc.getChildNodes().getLength();
NodeList nodeList = doc.getChildNodes();
//To get <elements> root node
Node firstNode = nodeList.item(0);
//To get childs element0...elementN
NodeList elementNodes = firstNode.getChildNodes();
//Last node is a text node
Node lastInnerNode = elementNodes.item(elementNodes.getLength()-2);
//To extract index of last tag
String lastInnerNodeName = lastInnerNode.getNodeName();
int lastNodeIndex = Integer.parseInt(lastInnerNodeName.substring(lastInnerNodeName.length()-1, lastInnerNodeName.length()));
XPathExpression xpathexpression;
//To extract every content
for (int i = 1; i <= lastNodeIndex; i++) {
xpathexpression = xpath.compile("//element"+i+"/text()");
Object result = xpathexpression.evaluate(doc, XPathConstants.STRING);
String texto = (String) result;
System.out.println("Item: "+texto);
}
}