Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.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_Algorithm_Parsing_Groovy - Fatal编程技术网

Java 有没有一种简单的方法可以将此文本解析为地图

Java 有没有一种简单的方法可以将此文本解析为地图,java,regex,algorithm,parsing,groovy,Java,Regex,Algorithm,Parsing,Groovy,我收到如下服务的回复。如何将其解析为映射?我首先想到在空白处拆分,但它不起作用,因为值可能包含空格,例如,在下面的响应中查看SA键的值 我想到的一个选择是在空白处拆分,前提是前面的字符是双引号。但不知道如何为此编写正则表达式 TX=“0000000000 10800001830001”FI=“”OS=“8”CI=“QU01SF1S2032”AW=“SSS”SA=“1525迎风大厅”在引号处解析。您甚至可以使用正则表达式来查找每个键/值对,假设每个值都在引号中。我唯一的问题是,如果一个值包含嵌入的

我收到如下服务的回复。如何将其解析为
映射
?我首先想到在空白处拆分,但它不起作用,因为值可能包含空格,例如,在下面的响应中查看SA键的值

我想到的一个选择是在空白处拆分,前提是前面的字符是双引号。但不知道如何为此编写正则表达式


TX=“0000000000 10800001830001”FI=“”OS=“8”CI=“QU01SF1S2032”AW=“SSS”SA=“1525迎风大厅”

在引号处解析。您甚至可以使用正则表达式来查找每个键/值对,假设每个值都在引号中。我唯一的问题是,如果一个值包含嵌入的引号,那么规则是什么?(它们是使用“\”或类似的方式逃逸的吗?不管怎样,下面的内容中目前没有考虑到这一点…)

例如:

(\w+)="([^"]*)"
这甚至会为您提供组#1和#2,它们可以分别用于提供键和值

使用Java的
Matcher.find()
方法在一个循环中运行它,直到找到所有对

示例代码:

String input = "TX=\"0000000000108000001830001\" FI=\"\" OS=\"8\" CI=\"QU01SF1S2032\" AW=\"SSS\" SA=\"1525 Windward Concourse\"";

Pattern p = Pattern.compile("\\s*(\\w+)=\"([^\"]*)\"\\s*");

Matcher m = p.matcher(input);
while(m.find()){
    System.out.println(m.group(1));
    System.out.println(m.group(2));
}
输出:

TX
0000000000108000001830001
FI

OS
8
CI
QU01SF1S2032
AW
SSS
SA
1525 Windward Concourse
虽然我没有使用
quoteChar()
功能,但是速度很快。可以找到示例,以及

控制台:

TX=0000000000108000001830001 FI= OS=8 CI=QU01SF1S2032 AW=SSS SA=1525 Windward Concourse Count: 6 0.623 ms
从文本的外观来看,它似乎可能是XML。是这样,还是该文本是服务的原始响应?如果是XML,可以使用Groovy的XmlSlurper轻松解析:

def input = '<root TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"></root>'
def xml = new XmlSlurper().parseText(input)

def map = xml.attributes()

map
的结果会和以前一样。

Geez,只需使用单引号;它的标签是Groovy:)@DaveNewton-我们将把它作为操作练习:-)@ziesemer-+1。但是我得到了“=”后面的valaue,它用双quoes打印为“0000000000 108000001830001”@Pangea,因为这就是输入中的值。你期待什么?"108000001830001"? 如果是这样的话,您需要将其解析为一个数字-但鉴于上述示例输入和要求,我不确定如何确定哪些值应作为数字处理,哪些值应作为字符串处理。@ziesemer-我问这个问题是因为您在响应中的示例输出不包含双引号。似乎需要使用replaceAll()方法来删除双引号。了解StreamTokenizerI很好,我只需要尝试一下
quoteChar()
;我认为这个解决方案过于复杂。除非有很大的性能限制,否则我建议使用一个更简单的解决方案,比如使用正则表达式(如果性能是一个限制,那么应该对它进行分析,看看它是否真的比正则表达式快,我对此表示怀疑)。@epidemian:是的,这就是为什么我引用了一个方便的解决方案。您也可以这样做:
defmap=(匹配为列表).collectEntries{[(it[1]):it[2]}
@tim_-yates Nice!我尝试在
match
对象上调用
collectEntries
,但它没有该方法,只有标准的迭代方法。我没有想到先把它转换成一个
列表。顺便说一句,一个
inject
也可以完成这个技巧=D
def input = '<root TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"></root>'
def xml = new XmlSlurper().parseText(input)

def map = xml.attributes()
def input = 'TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"'
def match = input =~ /(\w+)="([^"]*)"/

def map = [:]
match.each {
    map[it[1]] = it[2]
}