提取以字符串编码的长度字符串的正则表达式
Regex that extract string of length that is encoded in string
我要解析以下字符串:
X4IitemX6Nabc123
结构如下:
- X... 'field identifier'
的标记
- 4...项目(名称)的长度,将根据项目名称的长度而变化
- I...项目名称的标识符,不得提取,已修复
- 项目...应提取为“名称”的值
- X... 'field identifier'
的标记
- 6...项目(名称)的长度,将根据项目名称的长度而变化
- N... 项目编号的标识符,不得提取,已修复
- abc123... 应提取为“num”的值
字符串中只会包含这两个值,序列也始终相同(名称,nmuber)。
我目前所掌握的是
\AX(?I<namelen>\d+)U(?<name>.+)X(?<numlen>\d+)N(?<num>.+)$
但这并没有考虑到名称的长度包含在字符串本身中。不知何故,名称组中的 .+
应该替换为 .{4}
。我尝试了 {}
、{${namlen}}
但这并没有产生我期望的结果(在 rubular.com 或 regex.191 上)
有任何想法或进一步参考吗?
您要求的内容只能在允许在正则表达式模式中插入代码的语言中实现。
这是一个Perl example:
#!/usr/bin/perl
use warnings;
use strict;
my $text = "X4IitemX6Nabc123";
if ($text =~ m/^X(?<namelen>[0-9]+)I(?<name>(??{".{".$^N."}"}))X(?<numlen>[0-9]+)N(?<num>.+)$/) {
print $text . ": PASS!\n";
} else {
print $text . ": FAIL!\n"
}
# -> X4IitemX6Nabc123: PASS!
在其他语言中,使用两步法:
- 提取
X
、 后的数字
- 使用第一步的结果动态构建正则表达式。
看一个JavaScript例子:
const text = "X4IitemX6Nabc123";
const rx1 = /^X(\d+)/;
const m1 = rx1.exec(text)
if (m1) {
const rx2 = new RegExp(`^X(?<namelen>\d+)I(?<name>.{${m1[1]}})X(?<numlen>\d+)N(?<num>.+)$`)
if (rx2.test(text)) {
console.log(text, '-> MATCH!')
} else console.log(text, '-> FAIL!');
} else {
console.log(text, '-> FAIL!')
}
import re
text = "X4IitemX6Nabc123"
rx1 = r'^X(\d+)'
m1 = re.search(rx1, text)
if m1:
rx2 = fr'^X(?P<namelen>\d+)I(?P<name>.{{{m1.group(1)}}})X(?P<numlen>\d+)N(?P<num>.+)$'
if re.search(rx2, text):
print(text, '-> MATCH!')
else:
print(text, '-> FAIL!')
else:
print(text, '-> FAIL!')
# => X4IitemX6Nabc123 -> MATCH!
我要解析以下字符串:
X4IitemX6Nabc123
结构如下:
- X... 'field identifier' 的标记
- 4...项目(名称)的长度,将根据项目名称的长度而变化
- I...项目名称的标识符,不得提取,已修复
- 项目...应提取为“名称”的值
- X... 'field identifier' 的标记
- 6...项目(名称)的长度,将根据项目名称的长度而变化
- N... 项目编号的标识符,不得提取,已修复
- abc123... 应提取为“num”的值 字符串中只会包含这两个值,序列也始终相同(名称,nmuber)。
我目前所掌握的是
\AX(?I<namelen>\d+)U(?<name>.+)X(?<numlen>\d+)N(?<num>.+)$
但这并没有考虑到名称的长度包含在字符串本身中。不知何故,名称组中的 .+
应该替换为 .{4}
。我尝试了 {}
、{${namlen}}
但这并没有产生我期望的结果(在 rubular.com 或 regex.191 上)
有任何想法或进一步参考吗?
您要求的内容只能在允许在正则表达式模式中插入代码的语言中实现。
这是一个Perl example:
#!/usr/bin/perl
use warnings;
use strict;
my $text = "X4IitemX6Nabc123";
if ($text =~ m/^X(?<namelen>[0-9]+)I(?<name>(??{".{".$^N."}"}))X(?<numlen>[0-9]+)N(?<num>.+)$/) {
print $text . ": PASS!\n";
} else {
print $text . ": FAIL!\n"
}
# -> X4IitemX6Nabc123: PASS!
在其他语言中,使用两步法:
- 提取
X
、 后的数字
- 使用第一步的结果动态构建正则表达式。
看一个JavaScript例子:
const text = "X4IitemX6Nabc123";
const rx1 = /^X(\d+)/;
const m1 = rx1.exec(text)
if (m1) {
const rx2 = new RegExp(`^X(?<namelen>\d+)I(?<name>.{${m1[1]}})X(?<numlen>\d+)N(?<num>.+)$`)
if (rx2.test(text)) {
console.log(text, '-> MATCH!')
} else console.log(text, '-> FAIL!');
} else {
console.log(text, '-> FAIL!')
}
import re
text = "X4IitemX6Nabc123"
rx1 = r'^X(\d+)'
m1 = re.search(rx1, text)
if m1:
rx2 = fr'^X(?P<namelen>\d+)I(?P<name>.{{{m1.group(1)}}})X(?P<numlen>\d+)N(?P<num>.+)$'
if re.search(rx2, text):
print(text, '-> MATCH!')
else:
print(text, '-> FAIL!')
else:
print(text, '-> FAIL!')
# => X4IitemX6Nabc123 -> MATCH!