使用regexp拆分类似'foo = bar#baz = qo \#ox#al \ = pha = beta的字符串

时间:2011-05-01 17:04:31

标签: regex

这是一个快速的挑战。 取这个字符串foo=bar#baz=qo\#ox#al\=pha=beta,其中包含由#彼此分隔的键值对[pair]和=作为键和值之间的分隔符,并使用正则表达式将其拆分为其组件(perl,python,classic,等等) )。如果在键或值中遇到字符#和=,则它们以\为前缀。 因此,结果应该是键/值表:

KEY    | VALUE
foo    |  bar
baz    | qo#ox
al=pha | beta

如果你的正则表达式(分裂或匹配)只是将它分成#字符,你就得到100分。如果你设法分成一个密钥和值= =字符,那么收集额外的50分。

P.S。使用令牌解析和前瞻或后面解决这个问题是微不足道的,所以没有点。

4 个答案:

答案 0 :(得分:6)

#!/usr/bin/perl

use v5.10;
use strict;
use warnings;

my $input = 'foo=bar#baz=qo\#ox#al\=pha=beta';
my %table = $input =~ m'((?:\\.|[^\\=])+)=((?:\\.|[^\\#])+)#?'g;

for my $key (sort keys %table) { say "$key\t| $table{$key}" }

(编辑:在regexp上使用单引号,主要是为了防止StackOverflow认为#是注释字符)。

答案 1 :(得分:0)

这是一个两步过程:

  1. 拆分@'#'以获取键/值对列表
  2. 循环键/值对字符串并在'='处拆分;将令牌放入字典或地图。

答案 2 :(得分:0)

在Python中:

import re

string = "foo=bar#baz=qo\#ox#al\=pha=beta"

regx = re.compile('(?:(?<=\A)|(?<=#))((?:[^=]|(?<=\\\\)=)+)=((?:[^#]|(?<=\\\\)#)+)')

print regx.findall(string)

结果

[('foo', 'bar'), ('baz', 'qo\\#ox'), ('al\\=pha', 'beta')]

修改

没有兴趣回答:它不尊重措辞中表达的条件

答案 3 :(得分:-1)

如果您想在php 1班轮中执行 ALL ,请输入以下代码:

// your original text
$str = 'foo=bar#baz=qo\#ox#al\=pha=beta';

// php 1 liner to break it into name-value pairs as you wanted
$nvMap = eval('return array('.implode(',', preg_replace('~^([^\\\]+)\\\?(.*?)(?:(?<!\\\)=)([^\\\]+)\\\?(.*?)$~', '"$1$2"=>"$3$4"', preg_split("~(?<!\\\)#~", $str))).');');

输出

var_dump($nvMap);

array(3) {
  ["foo"]=>
  string(3) "bar"
  ["baz"]=>
  string(5) "qo#ox"
  ["al=pha"]=>
  string(4) "beta"
}