정규식은 중첩/균형 잡힌 구문을 지원하지 않습니다. 예를 들어 수학 문을 파싱하고 모든 여는 괄호에 적절하게 균형 잡힌 닫는 괄호가 있는지 확인하거나 XML 또는 HTML을 파싱하여 모든 요소가 제대로 닫히도록하려면보다 풍부한 표현법이 필요합니다. (학문적 인 설명을 위해서는 Chomsky's Hierarchy을 참조하십시오.)
중첩 된 구문으로 언어를 구문 분석하려면 '푸시 다운 오토 마톤'과 동일한 기능이 필요합니다. PDA), 두려워하지 않습니다.이 모든 멋진 용어는 실제로 구현하기가 쉽지 않습니다. 재귀 또는 루핑을 사용하거나 각 반복 내에서 정규 표현식을 사용하여 문제를 해결하거나 자신의 파싱 메서드를 간단하게 작성할 수 있습니다.
는 최근 우리의 나머지 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, 확장 문자열이 지정되지 않은 경우 결과의 모든 'first order'(FO) 속성을 반환합니다. 특정 속성의 이름이 지정되면 확장 용어 (확장 할 수있는 관계 속성의 이름을 지정하는 경우) 또는 용어를 좁히는 경우 (FO 속성의 이름을 지정하는 경우). 축소 용어가 지정된 경우 렌더링 된 결과에는 다음과 같은 내용이 포함됩니다. 요청한 용어 만 또한 요청 된 용어에 관계없이 항상 ID를 반환합니다.
위의 메서드는 확장 사양을 포함하는 원시 값만 구문 분석합니다. 키가 확장 스펙의 최상위 레벨에있는 단일 용어 인 Map을 생성합니다. 값은 확장 될 때 해당 용어에 적용해야 할 확장 스펙 (압축 된 상태로 남음)입니다. 이것은 회귀가 일어나는 곳입니다. 분명히이 방법보다 높은 수준에서 발생합니다. 여기에서 얻을 수 있다고 가정합니다.
이 방법은 상당히 강력합니다. 원시 값에는 불균형 중괄호와 쓰레기 문자가 포함될 수 있다고 가정합니다. 이것들이 발생하면 그것들을 무시하고 원시 값에서 가능한 한 많이 회수합니다. 그것은 '실패 마지막'접근 방식입니다.
기본적으로 이것은 우리가 팔로우하는/서비스중인 서비스 모델입니다. 이런 종류의 패턴은 ACCEPT 헤더에 올 것이며 우리는 그것을 분석 할 것입니다. 이러한 이름은 Java 필드 이름이므로 Java에서 필드 이름 지정에 사용할 수있는 문자를 여기에 적용 할 수 있다고 가정 할 수 있습니다. – Niranjan
제 경험상, 헤더 정보를 분석해야하는 경우 특히 헤더의 거래 데이터가 좋지 않습니다. 그러나 반드시 그렇게해야한다면 표준 __? __ 표시를 사용하여 쿼리 세그먼트/필드를 구분하십시오. 자신이 제공 할 수있는 데이터로 자신을 제한하면 누군가가 (실수로 또는 다른 방법으로) 쉼표, 괄호 또는 대괄호 문자를 전달하면 쿼리가 매우 쉽게 중단됩니다. – epluribusunix
안녕하세요, 저는 제대로 설명하지 못하고 있다고 생각합니다. 여기에는 어떤 데이터도 포함되지 않습니다.이 필드는 필드 이름과 같은 메타 데이터입니다. 또한 메타 데이터 만 포함됩니다. – Niranjan