gpt4 book ai didi

java - 解析 REST 服务的资源扩展

转载 作者:行者123 更新时间:2023-12-02 06:06:38 25 4
gpt4 key购买 nike

我们正在尝试为我们的 REST 服务构建资源扩展功能。资源扩展可以通过以下模式提供

    fields=field1,field2(sf1,sf2),field3[Format],field4(sf1,sf2,sf3)

What could be the best way to parse this? The parsing has to happen for every incoming request and hence, has to be a better performing.

We are trying to check if a regex can be defined for this. What could be the regex for such a pattern?

Edit (10-Mar-2014): The string contains only metadata (Java field names) and it can be also multi-level like

field1(sf1,sf2(sf21,sf22)),field2[Format],field3[Format],field4(sf1,sf2,sf3)

我应该使用正则表达式还是手动解析?

最佳答案

正则表达式不支持嵌套/平衡语法。例如,解析数学语句并确保每个左括号都有适当平衡的右括号,或者解析 XML 或 HTML 以确保每个元素正确关闭,都需要更具表现力的语法。 (有关学术解释,请参阅 Chomsky's Hierarchy,特别注意常规语言和上下文无关语言之间的差异。)

为了解析具有嵌套语法的语言,您需要相当于“下推自动机”(PDA),但不用担心 - 所有这些花哨的术语实际上实现起来都很简单。您可以使用递归或循环来解决问题,并在每次迭代中使用正则表达式,或者简单地构建您自己的解析方法。

我最近在 Rest API 中实现了完全相同的功能,虽然我的语法略有不同,但我怀疑您可能会发现此代码很有帮助:

/**
* Given a single packed string that defines a recursive set of fields,
* this will parse and return a Map of terms from the root level where the
* term is mapped to the packed string defining the sub-fields within that key.
*
* Assume the primary/root result is a Movie...
* --(raw==null) get all movie First Order (FO) attributes
* stars --get all movie FO, and expand stars relation
* title --get movies FO id and title
* title,stars --get movies FO id and title, and expand stars relation
*
* stars{} --get all movie FO, and expand stars relation (same as stars)
* stars{name} --get all movie FO, and expand stars relation getting star FO id and name
* stars{contractStudio} --get all movie FO, expand stars relation getting all star FO and expand stars contract studio
* stars{name,contractStudio} --get all movie FO, and expand stars relation getting star FO id and name and expand stars contract studio
* title,stars{name,contractStudio{name,founded}} --get movies FO id and title, and expand stars relation getting star FO id and name and expand stars contract studio with the studio FO name and founded date
*/
private Map<String, String> parseRequestParameter(String raw) {
if (raw == null || raw.isEmpty()) return Collections.emptyMap();
Map<String, String> results = new HashMap<>();
int i = 0;
int j = 0;
while (j < raw.length()) {
char c = raw.charAt(j);
//move j to end of attr name
while (c != '{' && c != ',' && ++j < raw.length()) {c = raw.charAt(j);}
String attr = raw.substring(i, i = j).trim();
if (!attr.isEmpty()) {
//capture the optional sub-expansion
if (c == '{') {
i++; //move i past the opening '{'
int pDepth = 1;
while (pDepth > 0 && ++j < raw.length()) { //pDepth is depth of nested { }
pDepth += (c = raw.charAt(j)) == '{' ? 1 : (c == '}' ? -1 : 0);
}
results.put(attr, raw.substring(i, j).trim());
if (++j < raw.length()) c = raw.charAt(i = j); //move i and c past the closing '}'
}
else {
results.put(attr, null);
}
}
//skip any unexpected suffix trash... only ',' marks next term.
while ((i = ++j) < raw.length() && c != ',') {c = raw.charAt(j);}
}
return results;
}

在我们的例子中,正如您可以从 javadoc 推断的那样,如果未指定扩展字符串,我们将返回结果的所有“一阶”(FO) 属性。如果指定了特定属性,则它们要么是扩展术语(如果它们命名可扩展的关系属性),要么是缩小术语(如果它们命名 FO 属性)。如果指定了任何缩小术语,则呈现的结果包含仅要求的条款。此外,无论请求什么条款,我们始终返回 ID。

上述方法仅解析包含扩展规范的原始值。它生成一个 Map,其中键是扩展规范顶层的单个术语。这些值是扩展规范(保持打包),您需要在该术语扩展时应用该规范。这就是回归发挥作用的地方。显然,这发生在比此方法更高的级别,我认为您可以从这里到达那里。

这个方法相当稳健。它假设原始值可能包含不平衡的花括号和垃圾字符。当遇到这些时,它将忽略它们,并尽可能地从原始值中回收。这是一种“最后失败”的方法。

关于java - 解析 REST 服务的资源扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22238832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com