正则表达式匹配除某些分隔符之外的任何内容

时间:2009-03-05 11:54:50

标签: java regex

我期待来自应用程序的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不起作用......有什么建议吗?

2 个答案:

答案 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|"上的字符串以获取列数组
  • 检查数组长度以确保列数正确
  • 迭代columns数组以处理数据。

这种方法当然也适用于单字符分隔符。