2009-10-22 3 views
3

부서를 나열하는 하위 메뉴가 있습니다. 이 뒤에는 각 부서에 'actPlan'+ department.name이라는 이름의 작업이 있습니다.문자열을 wash/validate하여 componentname에 할당하는 방법은 무엇입니까?

이제 이름이 세계의 이상한 문자를 포함 할 수 있지만 action.name에는 국제 문자가 포함될 수 없기 때문에 이것은 나쁜 생각이라는 것을 알고 있습니다. 분명히 Delphi IDE 자체는 문자열이 유효한 componentname인지 확인하는 몇 가지 메서드를 호출합니다. 누구든지 이것에 대해 더 알고 있습니까?

내가 대신

Action.name := 'actPlan' + department.departmentID; 

를 사용하는 아이디어를 가지고있다. 장점은 departmentID가 알려진 형식 인 'xxxxx-x'(여기서 x는 1 ~ 9)이므로 '-'를 예를 들어 밑줄로 바꾸면됩니다. 여기서 문제는 이러한 이전 액션 이름이 이미 개인 텍스트 파일에 유지된다는 것입니다. 갑자기 부서 이름을 ID에서 ID로 변경하면 예외가됩니다.

물론 예외를 처음으로 먹은 다음 해당 텍스트 파일을 검색하여 올바른 데이터로 바꾸고 다시로드하는 메서드를 호출 할 수 있습니다.

그래서 기본적으로 가장 우아하고 미래 지향적 인 방법으로이 문제를 해결합니다. 저는 D2007을 사용합니다.

답변

7

부품 이름은 단지 첫 번째 문자는 알파벳 또는 밑줄과 모든 후속 문자 숫자 또는 밑줄인지 여부를 확인 SysUtils를로부터 IsValidIdent 함수를 사용하여 검증된다.

해당 규칙에 맞는 문자열을 만들려면 정규화되지 않은 문자를 모두 제거한 다음 결과가 숫자로 시작되면 해당 문자를 추가하기 만하면됩니다.

이 변환은 유사한 이름에 대해 동일한 결과를 산출 할 수 있습니다. 원하는 내용이 아니라면 입력 문자열에서 계산 된 체크섬이나 부서 ID와 같이 문자열 끝에 고유 한 것을 추가 할 수 있습니다.

function MakeValidIdent(const s: string): string; 
var 
    len: Integer; 
    x: Integer; 
    c: Char; 
begin 
    SetLength(Result, Length(s)); 
    x := 0; 
    for c in s do 
    if c in ['A'..'Z', 'a'..'z', '0'..'9', '_'] then begin 
     Inc(x); 
     Result[x] := c; 
    end; 
    SetLength(Result, x); 
    if x = 0 then 
    Result := '_' 
    else if Result[1] in ['0'..'9'] then 
    Result := '_' + Result; 
    // Optional uniqueness protection follows. Choose one. 
    Result := Result + IntToStr(Checksum(s)); 
    Result := Result + GetDepartment(s).ID; 
end; 

델파이 2009 년 이후의 CharInSet 함수 호출로 두 번째 두 in 연산자를 대체합니다. 델파이 8 이전 버전에서는 첫 번째 in 연산자를 기존 for 루프로 변경하고 s에 색인을 지정합니다. (유니 코드 문자는 Delphi 집합과 잘 작동하지 않습니다.)

5

나는 문자열에서 파스칼 식별자를 만드는 루틴

// See SysUtils.IsValidIdent: 
function MakeValidIdent(const AText: string): string; 
const 
    Alpha = ['A'..'Z', 'a'..'z', '_']; 
    AlphaNumeric = Alpha + ['0'..'9']; 

    function IsValidChar(AIndex: Integer; AChar: Char): Boolean; 
    begin 
    if AIndex = 1 then 
     Result := AChar in Alpha 
    else 
     Result := AChar in AlphaNumeric; 
    end; 

var 
    i: Integer; 
begin 
    Result := AText; 
    for i := 1 to Length(Result) do 
    if not IsValidChar(i, Result[i]) then 
     Result[i] := '_'; 
end; 

를 작성했습니다. Classes.pas에서 FindUniqueName을 복사하여 MakeValidIdent의 결과에 적용 할 수도 있습니다.

+1

루틴이 올바르게 작동하지 않으면 첫 번째 문자의 숫자를 사용할 수 있습니다. – mghie

+0

고마워, 나는 결코 눈치 채지 못했다. 베로 코더가 할 수있는 것처럼 루틴을 사용하면 문제가되지 않습니다. 따라서 이름을 바꾸거나 구현을 조정할지 여부를 결정해야합니다. –

+0

이름을 변경하면 유효한 구성 요소 이름이 만들어지지 않습니다. Object Inspector에서 시도하십시오. 예를 들어 "42"는 유효한 이름이 아닙니다. – mghie

관련 문제