Java VML路径的字符串操作
您好,我正在尝试使用Java字符串操作解析VML路径值。我想检索路径中的所有命令,如MoveTo、LineTo、CurveTo、RLineTo(其他命令)及其相应的x和y坐标/参数 下面是要解析的示例数据,每个命令都有自己的x,y坐标Java VML路径的字符串操作,java,string,string-matching,stringtokenizer,vml,Java,String,String Matching,Stringtokenizer,Vml,您好,我正在尝试使用Java字符串操作解析VML路径值。我想检索路径中的所有命令,如MoveTo、LineTo、CurveTo、RLineTo(其他命令)及其相应的x和y坐标/参数 下面是要解析的示例数据,每个命令都有自己的x,y坐标 1. m1,1 l1,200,200,200,200,1 xe 2. m, l1,200,200,200,200,1 xe 你能建议一个算法或代码来检索命令和每个命令的参数吗? 例如,在数字1中 Command = moveto 'm' Command P
1. m1,1 l1,200,200,200,200,1 xe
2. m, l1,200,200,200,200,1 xe
你能建议一个算法或代码来检索命令和每个命令的参数吗?
例如,在数字1中
Command = moveto 'm'
Command Parameters = (x=1,y=1).
参考:
这有点奇怪,但我试着像这样使用StringTokenizer
StringTokenizer tokenizer = new StringTokenizer(path);
一位朋友建议使用StringTokenizer,它做了一些接近我目标的事情,它给了我以下数据。也许我可以利用StringTokenizer来满足我的需要
m1,1
l1,200,200,200,200,1
xe
对于#1,这里是理想的输出。(伪代码)
String命令\u type=“m”列出参数=添加(“1”、“1”)
字符串命令\u type=“l”列出参数=添加(“1”、“200”)
加上(“200”、“200”)
添加(“200”、“1”)
字符串命令\u type=“x”(可以没有参数)
字符串命令\u type=“e”(可以没有参数)
对于#2,这里是理想的输出。(伪代码)
String命令\u type=“m”List parameters=add(“0”,“0”)//因为没有指定x和y参数,所以我需要强制它们为0,0
字符串命令\u type=“l”列出参数=添加(“1”、“200”)
加上(“200”、“200”)
添加(“200”、“1”)
字符串命令\u type=“x”(可以没有参数)
字符串命令\u type=“e”(可以没有参数)
好的规范在这里很重要,但根据您的示例输入和输出,我猜:
字母->逗号分隔参数->字母->逗号分隔参数
我还注意到命令之间没有空格。e、 g.将xe作为两个单独的命令。这意味着在示例空间中没有任何意义,可以忽略
我还注意到命令都是单字母。(否则xe不会作为两个命令出现)
此外,参数必须成对出现,并且必须是数字。我在你的样本中没有看到负数,但我认为这是可能的。我还假设它们是整数而不是小数
因此,基于假定的规范,我可以为您提供一个可能的解决方案,让您仔细查看并了解它在做什么
package ic.ac.uk.relationshipvisualiser.app;
import java.util.ArrayList;
import java.util.List;
public class TmpNoFXTest {
private static class coOrd {
int x = 0;
int y = 0;
public coOrd(int p_x,int p_y) {
x=p_x;y=p_y;
}
public int getX() {return x;}
public int getY() {return y;}
}
private static class command {
String command = "";
List<coOrd> param_list = new ArrayList<coOrd>();
public command(String p_command) {
command = p_command;
}
private String parseOneParam(String p_inp) {
if (p_inp.equals("")) return "";
if (isLetter(p_inp.substring(0,1))) return p_inp;
int firstChar = 0;
for (int c=0;c<p_inp.length();c++) {
if (firstChar==0) {
if (isLetter(p_inp.substring(c,c+1))) {
firstChar = c;
}
}
}
String parms = p_inp.substring(0,firstChar);
if (parms.length()==0) return p_inp.substring(firstChar);
int x = 0;
int y = 0;
int p = 0;
String tmp = "";
while ((p<parms.length()) && (!parms.substring(p,p+1).equals(","))) {
tmp = tmp + parms.substring(p,p+1);
p++;
}
p++;
if (tmp.length()>0) {
x = Integer.parseInt(tmp);
}
tmp = "";
while ((p<parms.length()) && (!parms.substring(p,p+1).equals(","))) {
tmp = tmp + parms.substring(p,p+1);
p++;
}
if (p_inp.substring(p,p+1)==",") p++;
if (tmp.length()>0) {
y = Integer.parseInt(tmp);
}
param_list.add(new coOrd(x,y));
return p_inp.substring(p);
}
public String parseParams(String p_inp) {
if (p_inp.equals("")) return "";
while (!isLetter(p_inp)) {
p_inp = parseOneParam(p_inp);
}
return p_inp;
}
public String toString() {
String ret = "";
ret = "String command_type = \"" + command + "\"";
if (param_list.size()==0) return ret + " (can have no parameter )";
for (int c=0;c<param_list.size();c++) {
if (c>0) ret += "\n ";
ret += " List<String, String> parameters = add(\"" + param_list.get(c).getX() + "\", \"" + param_list.get(c).getY() + "\")";
}
return ret;
}
}
private static boolean isLetter(String p_inp) {
return p_inp.substring(0,1).matches("\\p{L}");
}
private static String parseSingleCommand(String p_inp, List<command> p_cmds) throws Exception {
//Read a single command off the incoming string and pass the remaining input back
String cmd = p_inp.substring(0,1);
if (!isLetter(p_inp)) throw new Exception("Error command starts with non letter (" + cmd + ")");
p_inp = p_inp.substring(1);
command c = new command(cmd);
p_inp = c.parseParams(p_inp);
p_cmds.add(c);
return p_inp;
}
private static List<command> parse(String p_inp) throws Exception {
List<command> r = new ArrayList<command>();
//spaces don't matter and I want to make this case-insensitive to minimise errors
p_inp = p_inp.toLowerCase();
p_inp = p_inp.replace(" ", "");
while (p_inp.length()>0) {
p_inp = parseSingleCommand(p_inp,r);
}
return r;
}
public static void main(String[] args) {
System.out.println("Start tmpTest");
List<String> tests = new ArrayList<String>();
tests.add("m1,1 l1,200,200,200,200,1 xe");
tests.add("m, l1,200,200,200,200,1 xe");
for (int c=0;c<tests.size();c++) {
System.out.println("Running test case " + c + " (" + tests.get(c) + ")");
try {
List<command> pr = parse(tests.get(c));
for (int d=0;d<pr.size();d++) {
System.out.println(pr.get(d).toString());
}
} catch (Exception e) {
e.printStackTrace();
return;
}
};
System.out.println("End tmpTest");
}
}
包ic.ac.uk.relationshipvisualiser.app;
导入java.util.ArrayList;
导入java.util.List;
公共类TmpNoFXTest{
私有静态类坐标{
int x=0;
int y=0;
公共合作组织(国际合作组织,国际合作组织){
x=p_x;y=p_y;
}
public int getX(){return x;}
public int getY(){return y;}
}
私有静态类命令{
String命令=”;
List param_List=new ArrayList();
公共命令(字符串p_命令){
命令=p_命令;
}
私有字符串parseOneParam(字符串p_inp){
如果(p_inp.equals)(“”)返回“”;
if(isLetter(p_inp.substring(0,1)))返回p_inp;
int firstChar=0;
对于(int c=0;c您能为3个示例中的每一个提供所需的输出吗?您好,感谢您的快速回复,我更新了示例并删除了第三个示例。:-)字符串标记器已折旧,请使用String.split(regex)为了同样的效果,谢谢你,这是一个很好的算法来解决这个需求。现在我面对的是更复杂的字符串值,比如:m@0,l@0@0,0@0,0@2@0@2@0,21600@1,21600@1@2,21600@2,21600@0@1@0@1,xe我目前正在进行这项工作,我将非常感谢任何帮助。
String command_type = "m" List<String, String> parameters = add("0", "0") // because the x and y parameters are not specified so I need to force them to 0,0
String command_type = "l" List<String, String> parameters = add("1", "200")
add("200", "200")
add("200", "1")
String command_type = "x" (can have no parameter )
String command_type = "e" (can have no parameter )
package ic.ac.uk.relationshipvisualiser.app;
import java.util.ArrayList;
import java.util.List;
public class TmpNoFXTest {
private static class coOrd {
int x = 0;
int y = 0;
public coOrd(int p_x,int p_y) {
x=p_x;y=p_y;
}
public int getX() {return x;}
public int getY() {return y;}
}
private static class command {
String command = "";
List<coOrd> param_list = new ArrayList<coOrd>();
public command(String p_command) {
command = p_command;
}
private String parseOneParam(String p_inp) {
if (p_inp.equals("")) return "";
if (isLetter(p_inp.substring(0,1))) return p_inp;
int firstChar = 0;
for (int c=0;c<p_inp.length();c++) {
if (firstChar==0) {
if (isLetter(p_inp.substring(c,c+1))) {
firstChar = c;
}
}
}
String parms = p_inp.substring(0,firstChar);
if (parms.length()==0) return p_inp.substring(firstChar);
int x = 0;
int y = 0;
int p = 0;
String tmp = "";
while ((p<parms.length()) && (!parms.substring(p,p+1).equals(","))) {
tmp = tmp + parms.substring(p,p+1);
p++;
}
p++;
if (tmp.length()>0) {
x = Integer.parseInt(tmp);
}
tmp = "";
while ((p<parms.length()) && (!parms.substring(p,p+1).equals(","))) {
tmp = tmp + parms.substring(p,p+1);
p++;
}
if (p_inp.substring(p,p+1)==",") p++;
if (tmp.length()>0) {
y = Integer.parseInt(tmp);
}
param_list.add(new coOrd(x,y));
return p_inp.substring(p);
}
public String parseParams(String p_inp) {
if (p_inp.equals("")) return "";
while (!isLetter(p_inp)) {
p_inp = parseOneParam(p_inp);
}
return p_inp;
}
public String toString() {
String ret = "";
ret = "String command_type = \"" + command + "\"";
if (param_list.size()==0) return ret + " (can have no parameter )";
for (int c=0;c<param_list.size();c++) {
if (c>0) ret += "\n ";
ret += " List<String, String> parameters = add(\"" + param_list.get(c).getX() + "\", \"" + param_list.get(c).getY() + "\")";
}
return ret;
}
}
private static boolean isLetter(String p_inp) {
return p_inp.substring(0,1).matches("\\p{L}");
}
private static String parseSingleCommand(String p_inp, List<command> p_cmds) throws Exception {
//Read a single command off the incoming string and pass the remaining input back
String cmd = p_inp.substring(0,1);
if (!isLetter(p_inp)) throw new Exception("Error command starts with non letter (" + cmd + ")");
p_inp = p_inp.substring(1);
command c = new command(cmd);
p_inp = c.parseParams(p_inp);
p_cmds.add(c);
return p_inp;
}
private static List<command> parse(String p_inp) throws Exception {
List<command> r = new ArrayList<command>();
//spaces don't matter and I want to make this case-insensitive to minimise errors
p_inp = p_inp.toLowerCase();
p_inp = p_inp.replace(" ", "");
while (p_inp.length()>0) {
p_inp = parseSingleCommand(p_inp,r);
}
return r;
}
public static void main(String[] args) {
System.out.println("Start tmpTest");
List<String> tests = new ArrayList<String>();
tests.add("m1,1 l1,200,200,200,200,1 xe");
tests.add("m, l1,200,200,200,200,1 xe");
for (int c=0;c<tests.size();c++) {
System.out.println("Running test case " + c + " (" + tests.get(c) + ")");
try {
List<command> pr = parse(tests.get(c));
for (int d=0;d<pr.size();d++) {
System.out.println(pr.get(d).toString());
}
} catch (Exception e) {
e.printStackTrace();
return;
}
};
System.out.println("End tmpTest");
}
}