问题描述:
假设要对android中的字符中进行翻译, 可以选择导出英文字符串资源, 然后对照翻译, 如果字符串中包含特殊字符& < > " ',
如: <string> i have & a apple</string>
翻译人员会觉得很奇怪, 所以可以将这些特殊字符转换成对应的字符后导出,如& < > 等, 最后翻译好后, 再将那些字符转换回去,不转换会编译报错
解题思路:
1.利用正则表达式, 以<>为模版, 将已经翻译好的字符串分离成2个列表, 一个放正常的tag,如<string>, 另一个放其他的字符串
2.将需要转换的字符转换回去
3.合并2个列表
具体代码如下:
private String convert(String value) {
String result = value;
System.out.println("origin: " + value);
Pattern pattern = Pattern.compile("\\<[\\s\\S]*?\\>");
Matcher matcher = pattern.matcher(result);
boolean match = false;
ArrayList<Integer> indexList = new ArrayList<Integer>();
ArrayList<String> strList = new ArrayList<String>();
ArrayList<String> tagList = new ArrayList<String>();
ArrayList<String> notagList = new ArrayList<String>();
while (matcher.find()) {
match = true;
indexList.add(matcher.start());
indexList.add(matcher.end());
tagList.add(value.substring(matcher.start(), matcher.end()));
}
if (match) {
strList.add(value.substring(0, indexList.get(0)));
for (int i = 0; i < indexList.size(); i++) {
if (i + 1 < indexList.size()) {
strList.add(value.substring(indexList.get(i),
indexList.get(i + 1)));
}
}
strList.add(value.substring(indexList.get(indexList.size() - 1)));
for (int i = 0; i < strList.size(); i++) {
if (i % 2 == 0 || i == strList.size() - 1) {
notagList.add(strList.get(i));
}
}
System.out.println("strList: " + strList.toString());
System.out.println("before nottagList: " + notagList.toString());
processNoTagList(notagList);
System.out.println("after nottagList: " + notagList.toString());
System.out.println("before tagList: " + tagList.toString());
ArrayList<String> processedTagList = new ArrayList<String>();
if(tagList.size() > 2) {
ArrayList<Integer> spliteIndexList = splitTagList(tagList);
System.out.println("tagList: " + tagList.toString());
for(int i = 0; i < spliteIndexList.size(); i = i + 2) {
int firstIndex = spliteIndexList.get(i);
int secondIndex = spliteIndexList.get(i + 1);
ArrayList<String> subTagList = new ArrayList<String>();
for(int j = firstIndex; j <= secondIndex; j++ ) {
subTagList.add(tagList.get(j));
}
System.out.println("i: " + i);
System.out.println("before subTagList: " + subTagList.toString());
processedTagList.addAll(processTagList(subTagList));
}
} else {
processedTagList = processTagList(tagList);
}
//System.out.println("allTagList: " + allTagList.toString());
if (strList.size() != processedTagList.size() + notagList.size()
&& notagList.size() - processedTagList.size() != 1) {
System.out
.println("error: "
+ "strList size not equals processedTagList size plus notagList size");
}
System.out.println("begin mergerList: " + strList.toString());
result = mergerList(processedTagList, notagList);
} else {
strList.add(value);
processNoTagList(strList);
result = strList.get(0);
}
System.out.println("result: " + result);
System.out.println("------------------------------------------------------------------------------");
return result;
}
private ArrayList<Integer> splitTagList(ArrayList<String> tagList) {
ArrayList<Integer> spliteIndexList = new ArrayList<Integer> ();
String firstTag = "";
int theSameTag = 0;
boolean updateFirstTag = true;
for(int i = 0; i < tagList.size(); i++) {
if(updateFirstTag) {
firstTag = tagList.get(i).substring(0,tagList.get(i).replace(">", " ").indexOf(" ")) + ">";
spliteIndexList.add(i);
}
if(i != 0 &&
updateFirstTag == false &&
(tagList.get(i).substring(0,tagList.get(i).replace(">", " ").indexOf(" ")) + ">")
.equals(firstTag)) {
theSameTag++;
}
updateFirstTag = false;
if(tagList.get(i).startsWith("</")
&& ("<" +tagList.get(i).substring(2,tagList.get(i).length() -1) + ">").equals(firstTag)
&& theSameTag == 0) {
spliteIndexList.add(i);
updateFirstTag = true;
} else if(i != 0 &&
tagList.get(i).startsWith("</") &&
("<" +tagList.get(i).substring(2,tagList.get(i).length() -1) + ">").equals(firstTag) &&
tagList.get(i).substring(2,tagList.get(i).length() -1)
.equals(tagList.get(i - 1).substring(1,tagList.get(i - 1).replace(">", " ").indexOf(" ")))) {
theSameTag--;
} else if(tagList.get(i).endsWith("/>") &&
(tagList.get(i).substring(0,tagList.get(i).replace(">", " ").indexOf(" ")) + ">").equals(firstTag)) {
spliteIndexList.add(i);
updateFirstTag = true;
} else {
continue;
}
}
if(spliteIndexList.size() % 2 != 0) {
spliteIndexList.add(tagList.size() - 1);
}
System.out.println("spliteIndexList: " + spliteIndexList);
return spliteIndexList;
}
private String mergerList(ArrayList<String> tagList,
ArrayList<String> notagList) {
int index = 0;
StringBuilder build = new StringBuilder();
while (index < tagList.size()) {
build.append(notagList.get(index) + tagList.get(index));
index++;
}
build.append(notagList.get(index));
return build.toString();
}
private ArrayList<String> processTagList(ArrayList<String> tagList) {
ArrayList<String> pairTagList = new ArrayList<String>();
ArrayList<Integer> pairTagListIndexInTaglist = new ArrayList<Integer>();
ArrayList<String> nestedTagList = new ArrayList<String>();
ArrayList<Integer> nestedTagListIndexInTaglist = new ArrayList<Integer>();
ArrayList<String> mergerTagList = new ArrayList<String>();
for(int i = 0; i < tagList.size(); i++) {
String hopeTag = "", nextTag;
if(pairTagListIndexInTaglist.contains(i)) {
continue;
}
if(nestedTagList.size() > 0 && tagList.get(i).startsWith("</")) {
hopeTag = "<" + tagList.get(i).substring(2,tagList.get(i).length() - 1);
if(nestedTagList.get(nestedTagList.size() -1).startsWith(hopeTag)) {
pairTagList.add(nestedTagList.remove(nestedTagList.size() -1));
pairTagList.add(tagList.get(i));
pairTagListIndexInTaglist.add(nestedTagListIndexInTaglist.remove(nestedTagListIndexInTaglist.size() -1));
pairTagListIndexInTaglist.add(i);
continue;
}
}
hopeTag = "</"+ tagList.get(i).substring(1,tagList.get(i).replace(">", " ").indexOf(" ")) + ">";
if(i + 1 < tagList.size()) {
nextTag = tagList.get(i+ 1);
} else {
nextTag = null;
}
if(nextTag != null && nextTag.equals(hopeTag)) {
if(!pairTagListIndexInTaglist.contains(i)) {
pairTagList.add(tagList.get(i));
pairTagList.add(tagList.get(i + 1));
pairTagListIndexInTaglist.add(i);
pairTagListIndexInTaglist.add(i + 1);
i++;
}
} else if(tagList.get(i).endsWith("/>")) {
if(!pairTagListIndexInTaglist.contains(i)) {
pairTagList.add(tagList.get(i));
pairTagListIndexInTaglist.add(i);
}
} else {
nestedTagList.add(tagList.get(i));
nestedTagListIndexInTaglist.add(i);
}
}
System.out.println("----pairTagList: " + pairTagList);
System.out.println("----pairTagListIndexInTaglist: " + pairTagListIndexInTaglist);
System.out.println("----nestedTagList: " + nestedTagList);
System.out.println("----nestedTagListIndexInTaglist: " + nestedTagListIndexInTaglist);
if(nestedTagList.size() > 0) {
int halfTag = nestedTagList.size() % 2 == 0 ? nestedTagList.size() / 2 : (nestedTagList
.size() / 2) + 1;
System.out.println("----halfTag: " + halfTag);
for (int i = 0; i < nestedTagList.size(); i++) {
String hopeTag, hopeTagPrefix;
String realTag;
if (i < halfTag) {
hopeTag = "</"
+ nestedTagList.get(i).substring(1,
nestedTagList.get(i).replace(">", " ").indexOf(" ")).trim()
+ ">";
realTag = nestedTagList.get(nestedTagList.size() - i - 1);
if (!hopeTag.equals(realTag)) {
System.out.println("----error tagIndex: " + i + " hopeTag: "
+ hopeTag + " realTag: " + realTag);
nestedTagList.set(i, "<" + nestedTagList.get(i).substring(1));
}
} else {
hopeTag = "<" + nestedTagList.get(i).substring(2);
hopeTagPrefix = hopeTag.substring(0, hopeTag.length() - 1);
realTag = nestedTagList.get(nestedTagList.size() - i - 1);
if (!realTag.startsWith(hopeTagPrefix)) {
System.out.println("----error tagIndex: " + i
+ " hopeTagPrefix: " + hopeTagPrefix + " realTag: "
+ realTag);
if(!realTag.contains(hopeTagPrefix))
nestedTagList.set(i, "<" + nestedTagList.get(i).substring(1));
}
}
}
}
for(int i = 0; i < tagList.size(); i ++) {
if(pairTagListIndexInTaglist.contains(i)) {
mergerTagList.add(pairTagList.get(pairTagListIndexInTaglist.indexOf(i)));
} else if(nestedTagListIndexInTaglist.contains(i)) {
mergerTagList.add(nestedTagList.get(nestedTagListIndexInTaglist.indexOf(i)));
}
}
System.out.println("----mergerTagList: " + mergerTagList);
return mergerTagList;
}
private ArrayList<String> processNoTagList(
ArrayList<String> notagList) {
for (int i = 0; i < notagList.size(); i++) {
if (notagList.get(i).equals(" ")) {
continue;
}
// do not adjust the order of contains("&")
if (notagList.get(i).contains("&")) {
notagList.set(i, notagList.get(i).replace("&", "&"));
}
if (notagList.get(i).contains("<")) {
notagList.set(i, notagList.get(i).replace("<", "<"));
}
if (notagList.get(i).contains(">")) {
notagList.set(i, notagList.get(i).replace(">", ">"));
}
if (notagList.get(i).contains("\"")) {
if(notagList.get(i).startsWith("\"") && notagList.get(i).endsWith("\"")
&& !notagList.get(i).equals("\"")
&& !notagList.get(i).equals("\"\"")) {
notagList.set(i,
notagList.get(i).substring(0,1) +
notagList.get(i).substring(1,notagList.get(i).length() - 1).replace("\"", """) +
notagList.get(i).substring(notagList.get(i).length() - 1));
} else {
notagList.set(i, notagList.get(i).replace("\"", """));
}
}
if (notagList.get(i).contains("'")) {
if(notagList.get(i).indexOf("'") != 0 &&
!notagList.get(i).substring(notagList.get(i).indexOf("'") - 1, notagList.get(i).indexOf("'")).equals("\\")) {
notagList.set(i, notagList.get(i).replace("'", "\\'"));
}
}
}
return notagList;
}
本文介绍了在Android开发中处理多国语言字符串翻译的方法。针对英文字符串资源中包含的特殊字符如&、<、>等,建议在翻译前转换为可见字符,翻译完成后再转回,以避免编译错误。通过正则表达式将字符串资源分离,然后转换特殊字符,最后合并处理后的字符串列表。

1万+

被折叠的 条评论
为什么被折叠?



