我试图解析,在PHP中,描述网络节点的数据文件。数据文件由4列组成,第4列是可选的:
<Node name> <Operating System> <Description> <SSL info>
。
SIG.SND.SERV ZOS A Big client (MF LPAR PROD)
ADC1 ZOS AMEX SSL
ADEPTRA.GB1.PROD LINUX BANK OF SOMEWHERE TLS
ADEPTRA.GB2.CQA LINUX BANK OF SOMEWHERE TLS
AIX.EG3C UNIX BARCLAYS S+
AIX.EG3P UNIX BARCLAYS S+
ADEPTRA.GB2.CQA LINUX FICO (ADEPTRA) LTD TLS
AIX.RMWDEV1 UNIX FDCS
AIX.RMWPROD1 UNIX FDCS
AIX-EFXWRWCK01 UNIX EQUIFAX EUROPE
ANB-DRC-CDFDI NT ARAB NATIONAL BANK (ANB) SSL
我的问题在于column3,它的描述可能有空格,而列4可能没有空格。
我已经尝试了以下REGEX(使用REGEX检查器在https://regex101.com/:
(S+)s+(S+)s+(S.+?S)s+(S.+)?
(这是我试图表达"非空白后跟一些空格,非空白后跟一些空格,由非空白分隔的字符后跟至少2个空格
可以工作,除非第四列不存在。我尝试使最后的空格和字符可选,结果在第3列和第4列匹配在一起:
(S+)s{2,} (S+)s{2,} (S.+S)(s{2,})? ?(S.+)?
我还尝试创建一个REGEX,指定'任何由非空白分隔的字符,后跟至少2个空格或字符串结束':
(S.+?S)[s{2}|$]
这也是"接近但没有雪茄"。
遗憾的是,是的-第一行的描述确实在单词之间有多个空格。
添加了一个链接到我的一个尝试:https://regex101.com/r/k9JlZu/1
您可以使用这个正则表达式在每行中捕获3或4组:
^(S+)h+(S+)h+(w+(?:hw+)*(?:h*([^)]+)(?:hw+)?)?)(?:h{2,}(S+))?$
RegEx演示
RegEx细节:
^
: Start(S+)
:在捕获组#1中匹配1+非空白字符h+
: Match 1+ whitespaces(S+)
:匹配捕获组#2中的1+非空白字符h+
: Match 1+ whitespaces(w+(?:hw+)*(?:h*([^)]+))?)
:捕获组#3以匹配空格分隔的单词可选后面跟着(...)
字符串(?:h+(S+))?
:最后一个可选的非捕获组,用于捕获捕获组#4中的1+非空白字符$
: End
代码:(Demo)
preg_match_all(
'/^(S+)h+(S+)h+(S+(?:hS+|h+([^)]+))*)(?:h+(S+))?/m',
$txt,
$m
);
var_export($m);
似乎只有第三组比较棘手。
我建议使用比anubhava当前显示的更短的子模式:
( # capture group #3
S+ # one or more visible characters
(?: # a non-capturing group
hS+ # a single horizontal space followed by one or more visible characters
| # or
h+([^)]+) # one or more horizontal spaces, opening parenthesis, one or more non-closing parentheses, closing parenthesis
)* # zero or more times
)
第四个/可选组件在非捕获组中捕获,包含一个0或1量词(?
)。
模式比较:(anubhava(423步)vs mickmackua(396步))
// anubhava
/^(S+)h+(S+)h+(w+(?:hw+)*(?:h*([^)]+)(?:hw+)?)?)(?:h{2,}(S+))?$/m
// mickmackusa
/^(S+)h+(S+)h+(S+(?:hS+|h+([^)]+))*)(?:h+(S+))?/m
所以我的模式更简洁/简洁在步骤方面更有效率。