2009-09-19 48 views
1

我想String.Split()使用逗号作为delimitter以下字符串:如何拆分可能包含分隔符的用户生成的字符串?

John,Smith,123 Main Street,212-555-1212 

以上内容是由用户输入的。如果他们在地址输入一个逗号,得到的字符串会导致问题String.Split(),因为你现在有5个区域,而不是4:

John,Smith,123 Main Street, Apt 101,212-555-1212 

我可以对所有用户输入使用与string.replace()更换别的东西逗号,然后再次使用与string.replace()东西转换回逗号:

value = value.Replace(",", "*"); 

然而,这仍然可以愚弄如果用户恰好使用占位符delimitter有“*”他们的投入。那么你最终会得到额外的逗号和结果中没有星号。

我看到网上的解决方案来处理逃脱delimitters,但我还没有发现这个看似常见的情况的解决方案。我错过了什么?

编辑:这就是所谓的delimitter collision

+3

你的问题与逃脱分隔符解决的问题有什么不同?即为什么不逃避分隔符? – 2009-09-19 16:50:12

+2

你说你可以在所有的用户输入中替换逗号,这听起来像是在这个时候值是分开的。他们为什么然后把它们串成一个串? – gix 2009-09-19 16:52:51

回答

2

一个万无一失的解决方案将用户输入转换为base64,然后用逗号分隔。这意味着你必须在解析后转换回来。

+0

非常好。非常感谢。这绝不会发生在我身上。 – royco 2009-09-24 18:34:08

3

这可能不是一个选择,但会被它不会是更容易使用了非常少见的性格,说管道|,为您的分隔符,不允许在一审中输入这个人物?

+0

是的,这就是我的原始代码所做的。它工作正常,但我正在寻找更通用的解决方案。 – royco 2009-09-24 18:36:03

+0

公平点鲍勃不确定您是否尝试过原始问题的简单解决方案。像base64的答案一样。 – voiddog 2009-09-25 05:58:55

3

如果这是CSV,地址应该用引号括起来。解析文本时,CSV解析器广泛应用于此。

John,Smith,"123 Main Street, Apt. 6",212-555-1212 
0

你可以尝试把引号,或者一些其他的开始和结束的分隔符,围绕每个用户输入,而忽略一组引号之间的任何特殊字符。

这真的归结为清理用户输入的情况。您只应在用户输入中允许所需的字符,并拒绝/剥离用户的无效输入。这样你可以使用你的星号分隔符。

最好的解决办法就是以某种方式定义无效字符,并且拒绝非有效字符,然后使用nonvalid字符(这将不会出现在输入,因为它们是“禁止”),你定界符

+0

为什么downvote?特别是当我开始提出什么是当前最有回报的答案时,试图揭示更好的解决方案? – 2009-09-19 19:24:32

-1

礼貌地提醒正确形成街道地址在美国和加拿大应该不会包含任何标点无论如何,也许你的用户?

的受损的数据自动地转换成有用的数据的方法,是不启发式逻辑非平凡。您可以尝试通过调用第三方地址格式库来应用USPS格式规则来外包解析。

即使USPS也要求用户通过在地址“canonicalizer”页面(http://zip4.usps.com/zip4/welcome.jsp)上将地址的组成部分输入到不同字段中来执行大部分工作。

+0

虽然我想支持美国和加拿大以外的地址。 – royco 2009-09-24 18:36:52

0

不允许用户输入您用作分隔符的那个字符。我个人觉得这是最好的方法。

0

滑稽的解决方案(工作,如果地址是昏迷的唯一字段):

分割字符串昏迷。前两个部分将是姓名和姓氏;最后一部分是电话 - 把他们带走。结合其余的昏迷回 - 这将是地址;)

4

这是一个常见的情况 - 你有一些任意的字符串值,你想组成一个结构,它本身是一个字符串,但不允许的值干扰周围结构的分隔符。

您有几种选择:

  1. 输入限制:如果您的方案可以接受的,最简单的办法就是限制中的值使用的分隔符。在你的具体情况下,这意味着不允许使用逗号。
  2. 编码:如果输入限制不合适,下一个最简单的选项就是编码整个输入值。选择在其可能输出范围内没有分隔符的编码(例如,Base64在其编码输出中不包含逗号)
  3. 转义分隔符:稍微复杂一点的选择是为转义分隔符提供约定。如果您正在使用像CSV这样的主流技术,则转义问题很可能已经解决,并且您可以使用标准库。如果不是的话,那么需要考虑一个完整的转义系统并实现它。

如果您可以灵活地不使用CSV来进行数据表示,则会打开大量其他选项。 (例如考虑这样参数化SQL查询回避输入通过从查询字符串分开存储的参数值逸出的复杂性的方式。)

0

在某种意义上,用户已经“逃逸”的逗号与空间之后。

所以,试试这个:

string[] values = RegEx.Split(value, ",(?![ ])"); 

用户仍然可以打破这一点,如果他们不把一个空间,还有一个更简单的方法(使用引号包含逗号值的标准CSV方法),但是这会为你提供的用例做诀窍。

一个更多的解决方案:提供一个“地址2”字段,这是公寓号码传统上会去的地方。如果用户懒惰,用户仍然可以分解它,但是他们实际上会在 address2之后破坏字段

相关问题