我期待来自应用程序的String看起来像:
约翰| COL-DELIM | DOE | COL-DELIM | 55 | ROW-DELIM |乔治| COL-DELIM |杰特森| COL-DELIM | 90 | ROW-DELIM |
我想做两件事:
1)验证字符串“看起来”是否正确(即它是否与正则表达式匹配)
2)拉出每个“行”,然后能够解析每一行
分隔符之间的值(| COL-DELIM |和| ROW-DELIM |)可以是任何值(不仅仅是字符串,数字等)。
(()(\ |。COL-DELIM \ |。)()(\ | COL-DELIM \ |。)(*)(\ | ROW-DELIM \ |))+
当然,对于(。*)事物的b / c不起作用......有什么建议吗?
答案 0 :(得分:6)
人们似乎没有得到这样的事实:他们不必使用RE(或SQL,但这是另一个问题:-)用于每个任务,特别是那些程序代码更清晰。
如果你限制自己使用RE,我认为这是缺乏远见。
我只需按令牌处理字符串,令牌就是:
从空列列表开始,然后提取(使用indexOf / substring stuff)到第一个下一行/列分隔符,将该文本添加到列列表中。
如果分隔符是列,请继续。
如果分隔符是行,请检查列数并根据需要处理列表。
如果没有最终的行分隔符且列列表非空,则格式无效。
很抱歉,如果你真的在使用RE方法,但我认为这不是必需的(甚至是可取的)。
伪代码(只有第一次切割,可能略有错误)如下:
def processStr(s):
if not s.endsWith ("|ROW-DELIM|"):
error "Invalid format"
columnList = []
while not s.equals (""):
nextRowDelim = s.indexOf ("|ROW-DELIM|")
nextColDelim = s.indexOf ("|COL-DELIM|")
if nextColDelim == NotFound:
nextColDelim = nextRowDelim + 1
nextDelim = minimumOf (nextRowDelim,nextColDelim)
columnList.add (s.substring (0, nextDelim))
s = s.substring (nextDelim)
if nextDelim == nextRowDelim:
s = s.substring (length ("|ROW-DELIM|"))
processColumns (columnList)
columnList = []
else:
s = s.substring (length ("|COL-DELIM|"))
您可以轻松添加代码以检查此代码中的正确列数,或者processColumns()
中的代码,如果您愿意的话。
答案 1 :(得分:3)
您不必使用".*"
来匹配“任何内容”。事实上,在大多数情况下,".*"
是错误的。
如果您的col-delim是单个字符(例如“;”),您可以使用它来匹配列:
[^;]* // "anything that's *not* a semi-colon"
([^;]*);([^;]*);([^;]*)\n // three columns, ending with \n
由于此任务本质上是解析CSV,并且正则表达式不完全是解析的最佳工具,我建议您查找Java CSV解析包。
如果"|COL-DELIM|"
和"|ROW-DELIM|"
确实是固定的字符序列,我建议你split()
上的字符串而不是依赖正则表达式。
"|ROW-DELIM|"
以获取“行”字符串数组"|COL-DELIM|"
上的字符串以获取列数组这种方法当然也适用于单字符分隔符。