我在正則運算式方面并不是非常多才多藝,尤其是多行,所以我希望有人能在這里幫助我。
基于以下示例,我正在嘗試查找所有型別為 Code 且沒有設定“TableRelation”屬性的欄位定義。
所以在這個例子中,這將是欄位“Holding Name”
table 123 "MyTable"
{
fields
{
field(1000; "Created on"; Date)
{
Caption = 'Created on';
DataClassification = CustomerContent;
Editable = false;
}
field(2000; "Created by"; Code[50])
{
Caption = 'Created by';
TableRelation = User."User Name";
DataClassification = CustomerContent;
Editable = false;
}
field(3000; Resigned; Boolean)
{
Caption = 'Resigned';
DataClassification = CustomerContent;
}
field(4000; "Holding No."; Code[20])
{
Caption = 'Holding No.';
TableRelation = Contact."No." where(Type = const(Company));
DataClassification = CustomerContent;
trigger OnValidate()
var
[...]
begin
[...]
end;
}
field(4010; "Holding Name"; Code[100])
{
Caption = 'Holding Name';
DataClassification = CustomerContent;
}
field(5000; "Geocoding Entry No."; Integer)
{
Caption = 'Geocoding Entry No.';
DataClassification = CustomerContent;
}
}
keys
{
key(AppliesToContact; "Holding No.", "Holding Name", "Company Level") { }
}
}
我設法正確匹配“代碼”型別的欄位...... field\(\d ;. ; ?(?:C|c)ode\[\d \]\)\n?\s*\{(?:\n|.)*?\}
但我不知道如何正確排除包含“TableRelation”的匹配項,至少這不像我希望的那樣作業。- 我得到了一個巨大的匹配:-(
field\(\d ;. ; ?(?:C|c)ode\[\d \]\)\n?\s*\{((?!(T|t)able(R|r)elation)\n*.*)*?\}
ps 如果您想知道:我正在決議的示例是用 AL-Language 撰寫的,這是 MS Business Central 的專有語言。
uj5u.com熱心網友回復:
您可以field(使用以開頭的否定字符類匹配右括號之前的方括號之間的數字[^
同樣的否定字符類方法也可以用于TableRelation在花括號之間斷言 not 。
這并不是說你可以寫(?:C|c)為[Cc]使用字符類,而不是使用交替|
假設欄位后的大括號有一個非嵌套的閉合花括號:
field\([^()] ; ?[Cc]ode\[\d \]\)\s*{(?![^{}]*[Tt]able[Rr]elation)[^{}]*}
模式匹配:
field\([^()]匹配field(和 1 以外的字符()(也可以匹配換行符); ?[Cc]ode匹配;可選空間和代碼/代碼\[\d \]\)匹配[1 個數字])\s*{匹配可選的空白字符(也可以匹配換行符)和{(?![^{}]*[Tt]able[Rr]elation)負前瞻,TableRelation在 openin curly 之后斷言不[^{}]*匹配任何字符的可選重復,除了{}}比賽結束}
查看正則運算式演示。
uj5u.com熱心網友回復:
通過無案例研究和允許原子組和所有格量詞的正則運算式引擎,您可以撰寫:
\bfield\((?>[^);]*;\s*)*code\b[^)]*\)\s*{(?>[^\w}]* (?!tablerelation\s*=)\w )*[^\w}]*}
演示
這種模式基于否定字符類來阻止貪婪的量詞,如四只鳥的答案。原子組(?>...)和所有格量詞* 用于減少回溯。特別是,tablerelation僅在具有否定前瞻的一系列非單詞字符之后測驗存在。請注意,該code部分可以在括號之后的任何位置field。
uj5u.com熱心網友回復:
以下正則運算式可以捕獲Code[...]沒有“TableRelation”的區域的值。
/field\([^)] ; Code\[(\d )\]\)\n\s {((?!TableRelation).) ?}\n/gs
它使用g(global) 和s(dotall) 標志。
這個正則((?!TableRelation).) ?運算式的一個顯著部分是運算式。
(?!TableRelation): 負前瞻(不應該出現)((?!TableRelation).) ?: 沒有'TableRelation',盡可能少匹配
我創建了一個簡單的 JS 片段。該代碼使用兩個步驟來提取。
const regexp = /field\([^)] ; Code\[(\d )\]\)\n\s {((?!TableRelation).) ?}\n/gs;
const target = `
table 123 "MyTable"
{
fields
{
field(1000; "Created on"; Date)
{
Caption = 'Created on';
DataClassification = CustomerContent;
Editable = false;
}
field(2000; "Created by"; Code[50])
{
Caption = 'Created by';
TableRelation = User."User Name";
DataClassification = CustomerContent;
Editable = false;
}
field(3000; Resigned; Boolean)
{
Caption = 'Resigned';
DataClassification = CustomerContent;
}
field(4000; "Holding No."; Code[20])
{
Caption = 'Holding No.';
TableRelation = Contact."No." where(Type = const(Company));
DataClassification = CustomerContent;
trigger OnValidate()
var
[...]
begin
[...]
end;
}
field(4010; "Holding Name"; Code[100])
{
Caption = 'Holding Name';
DataClassification = CustomerContent;
}
field(4050; "Holding Name"; Code[80])
{
Caption = 'Holding Name 2';
DataClassification = CustomerContent;
}
field(5000; "Geocoding Entry No."; Integer)
{
Caption = 'Geocoding Entry No.';
DataClassification = CustomerContent;
}
}
keys
{
key(AppliesToContact; "Holding No.", "Holding Name", "Company Level") { }
}
}
`;
// step 1: extract field(...){...} chunks that do not contain "TableRelation"
const matchedBlocks = target.match(regexp);
// step 2: extract code values
const codes = matchedBlocks.map(m => m.match(/; Code\[(\d )\]/)[1] );
console.log(codes);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/409288.html
標籤:
