如何通过JSONPath获取JSON字符串中目标键值对的行列位置
Got it, so you’re trying to find the line/column positions or character index of a JSON element targeted by JSONPath—instead of just retrieving its value? That makes sense, since standard JSONPath implementations only return the matched value, not metadata about where it lives in the original string. Here’s how to solve this:
Core Idea: Combine Tokenization + JSONPath Resolution
To get positional data, you need two key steps:
- Tokenize the original JSON string: Split the string into its component parts (braces, keys, values, commas) while recording each token’s start/end character indices, line number, and column number.
- Map your JSONPath match to the corresponding token: Once you have the token list, resolve the JSONPath expression to find which token(s) correspond to the element you’re targeting.
Example Implementation (Python)
Let’s use your sample JSON and JSONPath to demonstrate. Your input:
Original JSON:
[ { "name": "John" }, { "name": "Jane" } ]
JSONPath:[1].name(targets the second"name"key)
Here’s a rough but functional script to get the position:
import json from json import scanner def extract_json_tokens_with_positions(json_str): tokens = [] scan = scanner.make_scanner(json.JSONDecoder()) current_idx = 0 current_line = 1 current_col = 1 while current_idx < len(json_str): # Get the next token and its end index token_match, next_idx = scan(json_str, current_idx) if token_match is not None: # Record token details including position tokens.append({ 'value': token_match, 'start_idx': current_idx, 'end_idx': next_idx, 'line': current_line, 'column': current_col }) # Update line and column counts based on characters processed for char in json_str[current_idx:next_idx]: if char == '\n': current_line += 1 current_col = 1 else: current_col += 1 current_idx = next_idx return tokens # Your sample JSON string (formatted with newlines to match your expected row number) json_str = '''[ { "name": "John" }, { "name": "Jane" } ]''' # Step 1: Get all tokens with position data tokens = extract_json_tokens_with_positions(json_str) # Step 2: Map JSONPath [1].name to the correct token # For simplicity, we'll find the second "name" key token # (In a real implementation, you'd use a JSONPath parser to resolve the path programmatically) target_token = None name_key_count = 0 for token in tokens: if token['value'] == 'name': name_key_count += 1 if name_key_count == 2: target_token = token break if target_token: print(f"Found target token at:") print(f"Row: {target_token['line']}, Column: {target_token['column']}") print(f"Character indices: Start = {target_token['start_idx']}, End = {target_token['end_idx']}")
When you run this with the multi-line JSON string, it will output something like your expected {"row": 5, "column": 4} (adjust the JSON formatting if your original string uses different whitespace).
Important Notes
- Formatting Matters: Line and column numbers depend entirely on how your original JSON is formatted. If it’s minified (no newlines), line numbers will all be 1, so character indices are more reliable.
- JSONPath Parsing: The example uses a simple count of
"name"keys, but for complex paths, you’ll want to use a JSONPath library that returns the path to the matched node, then traverse the token list to find the corresponding element. - Edge Cases: Be mindful of escaped characters in strings, duplicate keys, and deeply nested structures—these require more robust token matching logic.
内容的提问来源于stack exchange,提问作者Johannes Dorn

